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/dev/midictl.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: midictl.h,v 1.3 2008/04/28 20:23:47 martin Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 2006 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Chapman Flack.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 #ifndef _SYS_DEV_MIDICTL_H_
   33 #define _SYS_DEV_MIDICTL_H_
   34 
   35 /*
   36  * General support for MIDI controllers, registered parameters, and
   37  * nonregistered parameters. It interprets MIDI messages that update
   38  * these values, maintains the associated state, and provides an API
   39  * for obtaining the current value of any controller or parameter and
   40  * tracking changes to it.
   41  *
   42  * One function provides the interface for message parsing. When a message
   43  * is received, once it has been determined to be a MIDI_CTL_CHANGE message,
   44  * simply call midictl_change(&mc, chan, ctlval) where chan is the channel
   45  * extracted from the first byte, and ctlval points to the remaining two
   46  * bytes of the message received.
   47  *
   48  * The API for reading the state is equally simple. Use
   49  * midictl_read(&mc, chan, ctlr, dflt)
   50  * midictl_rpn_read(&mc, chan, rpn, dflt)
   51  * midictl_nrpn_read(&mc, chan, nrpn, dflt)
   52  * to read the current value of controller #ctlr, RP #rpn, or NRP #nrpn,
   53  * respectively. (For 14-bit controllers, use the MSB number as ctlr, not
   54  * the LSB number.) You get the complete current value; for 14-bit controllers
   55  * and parameters you get a single 14-bit integer without fussing about the
   56  * multiple MIDI messages needed to set it. If you read a controller or
   57  * parameter that no MIDI message has yet written, you get back the value dflt.
   58  * If you read one whose MSB or LSB only has been written, you get what you
   59  * would get if the value had been dflt before the write.
   60  *
   61  * The functions may be called from any context but reentrant calls operating
   62  * on the same midictl are unsupported, with one exception: calls back into
   63  * midictl from a notify handler it has called are permitted. If you are
   64  * calling midictl_change in a driver function called by midi(4), you are ok
   65  * as midi(4) itself serializes its calls into the driver. For other uses,
   66  * avoiding reentrant calls is up to you.
   67  *
   68  * A strict division of labor limits complexity. This module knows as little
   69  * about the meanings of different MIDI parameters and controllers as possible
   70  * to do its job: it knows which controllers are overloaded to serve as
   71  * channel mode messages, and which are overloaded to provide access to the
   72  * RPN and NRPN space. It knows which controllers are 14-bit, 7-bit, or 1-bit
   73  * according to the table online at midi.org. (All parameters are treated as
   74  * 14-bit.) It does not know or care about the specified default values;
   75  * client code is expected to know those defaults for whatever controls it
   76  * actually implements, and supply them when calling midictl_*read(). That
   77  * avoids the need for a large table of specified values for things most
   78  * clients will never read. A header file defining the official defaults could
   79  * be useful for clients to include for use when calling midictl_*read, but
   80  * is not part of this module. Reset All Controllers is simply handled by
   81  * forgetting controllers have been written at all, so the next read by
   82  * the client will return the client's supplied default.
   83  *
   84  * An incoming MIDI stream may refer to many controllers and parameters the
   85  * client does not implement. To limit memory use, messages are ignored by
   86  * default if they target a controller or parameter the client has never
   87  * read. To indicate which controllers/parameters it supports, the client
   88  * should simply read them when starting.
   89  *
   90  * Where the task is to generically process some MIDI stream without losing
   91  * data, accept_any_ctl_rpn can be set to 1 in the midictl structure, and
   92  * state will be kept for any incoming controller or RPN update. The separate
   93  * flag accept_any_nrpn enables the same behavior for nonregistered parameters.
   94  *
   95  * Whenever a change is made to any value for which state is being kept, the
   96  * notify function will be called with MIDICTL_CTLR, MIDICTL_RPN, or
   97  * MIDICTL_NRPN, the channel, and the controller, rp, or nrp number,
   98  * respectively. The controller number will never refer to the LSB of a 14-bit
   99  * controller. The new /value/ is not included; if the change is of interest,
  100  * the client reads the value and thereby supplies the default (which can still
  101  * be needed if the update is to half of a 14-bit value). The notify function
  102  * is also called, with appropriate evt codes, on receipt of channel mode
  103  * messages.
  104  * 
  105  * Reset All Controllers:
  106  *
  107  * The Reset All Controllers message will cause this module to forget settings
  108  * for all controllers on the affected channel other than those specifically
  109  * excepted by MIDI RP-015. Registered and nonregistered parameters are not
  110  * affected. The notify function is then called with evt = MIDICTL_RESET.
  111  *
  112  * The client's response to MIDICTL_RESET should include reading all
  113  * controllers it cares about, to ensure (if the accept_any_ctl_rpn flag is not
  114  * set) that they will continue to be tracked. The client must also reset to
  115  * defaults the following pieces of channel state that are not managed by this
  116  * module, but required by RP-015 to be reset:
  117  *  Pitch Bend
  118  *  Channel Pressure
  119  *  Key Pressure (for all keys on channel)
  120  * The client does NOT reset the current Program.
  121  */
  122 #include <sys/midiio.h>
  123 #include <sys/stdint.h>
  124 
  125 /*
  126  * Events that may be reported via a midictl_notify function.
  127  * Enum starts at 1<<16 so that enum|key can be used as a switch expression.
  128  * Key is 0 except where shown below.
  129  */
  130 typedef enum {
  131         MIDICTL_CTLR      = 1<<16,      /* key=ctlr */
  132         MIDICTL_RPN       = 2<<16,      /* key=rpn */
  133         MIDICTL_NRPN      = 3<<16,      /* key=nrpn */
  134         MIDICTL_RESET     = 4<<16,      /* Reset All Controllers received */
  135         MIDICTL_NOTES_OFF = 5<<16,      /* All Notes Off received */
  136         MIDICTL_SOUND_OFF = 6<<16,      /* All Sound Off received */
  137         MIDICTL_LOCAL     = 7<<16,      /* if (key) localIsOn else localIsOff */
  138         MIDICTL_MODE      = 8<<16       /* key=mode(1-4)? TBD unimplemented */
  139 } midictl_evt;
  140 
  141 /*
  142  * midictl_notify(void *cookie, midictl_evt evt,
  143  *                uint_fast8_t chan, uint_fast16_t key)
  144  */
  145 typedef void
  146 midictl_notify(void *, midictl_evt, uint_fast8_t, uint_fast16_t);
  147 
  148 typedef struct midictl_store midictl_store;
  149 
  150 typedef struct {
  151         uint_fast8_t accept_any_ctl_rpn:1; /* 0 ==> ignore chgs for unqueried */
  152         uint_fast8_t accept_any_nrpn:1;    /* likewise for NRPNs */
  153         uint_fast8_t base_channel; /* set >= 16 to ignore any MODE messages */
  154         void *cookie;              /* this value will be passed to notify */
  155         midictl_notify *notify;
  156         /* */
  157         uint16_t rpn;
  158         uint16_t nrpn;
  159         midictl_store *store;
  160 } midictl;
  161 
  162 extern void
  163 midictl_open(midictl *);
  164 
  165 extern void
  166 midictl_close(midictl *);
  167 
  168 /*
  169  * Called on receipt of a Control Change message. Updates the controller,
  170  * RPN, or NRPN value as appropriate. When updating a controller or RPN that
  171  * is defined in the spec as boolean, all values that by definition represent
  172  * false are coerced to zero. Fires the callback if a value of interest has
  173  * been changed.
  174  * ctlval: points to the second byte of the message (therefore, to a two-
  175  * byte array: controller number and value).
  176  * midictl_change(midictl *mc, uint_fast8_t chan, uint8_t *ctlval);
  177  */
  178 extern void
  179 midictl_change(midictl *, uint_fast8_t, uint8_t *);
  180 
  181 /*
  182  * Read the current value of controller ctlr for channel chan.
  183  * If this is the first time querying this controller on this channel,
  184  * and accept_any_ctl_rpn is false, any earlier change message for it
  185  * will have been ignored, so it will be given the value dflt, which is
  186  * also returned, and future change messages for it will take effect.
  187  * If the controller has a two-byte value and only one has been explicitly set
  188  * at the time of the first query, the effect is as if the value had been
  189  * first set to dflt, then the explicitly-set byte updated.
  190  * midictl_read(midictl *mc, uint_fast8_t chan,
  191  *              uint_fast8_t ctlr, uint_fast16_t dflt);
  192  */
  193 extern uint_fast16_t
  194 midictl_read(midictl *, uint_fast8_t, uint_fast8_t, uint_fast16_t);
  195 
  196 /*
  197  * As for midictl_read, but for registered parameters or nonregistered
  198  * parameters, respectively.
  199  */
  200 extern uint_fast16_t
  201 midictl_rpn_read(midictl *mc, uint_fast8_t, uint_fast16_t, uint_fast16_t);
  202 extern uint_fast16_t
  203 midictl_nrpn_read(midictl *mc, uint_fast8_t, uint_fast16_t, uint_fast16_t);
  204 
  205 #endif /* _SYS_DEV_MIDICTL_H_ */

Cache object: d1e71ac4a817d00ceed4a9374e9adddc


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