/* ========================================================================
* Copyright (C) 1998-2001 by Tobias Kunze Briseņo. All Rights Reserved.
*
* This library and its accompanying code is free software; you can
* redistribute it and/or modify it under the terms of the GNU Library
* General Public License as published by the Free Software Foundation;
* either version 2 of the License, or (at your option) any later version.
*
* This code is distributed WITHOUT ANY WARRANTY, in particular without
* the warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Library General Public License for more details.
*
* Suggestions, comments, or bug reports are welcome. Please visit the
* project site at
* ========================================================================
*
*
* Summary: Mi_D API Declarations
*
* Description: See the individual entry points below.
*
* Bugs:
*
*
* $Source: /cvsroot/mi-d/mi_d/include/mi_d.h,v $
* $Revision: 1.2 $
* $Date: 2001/05/05 03:01:02 $
*/
#ifndef MI_D_H
#define MI_D_H
#include
/* ===========================================================================
*
* API Result Codes and Constants
*
*/
/* API Result Codes */
static const int mi_dNoErr = 0;
static const int mi_dErr = -1;
static const int mi_dOutOfMemory = -3;
static const int mi_dOutOfBounds = -100;
static const int mi_dUndefinedFlag = -102;
static const int mi_dNullHandle = -103;
static const int mi_dIllegalValue = -104;
static const int mi_dEnvChanged = -110;
static const int mi_dNoInterfaces = -111;
static const int mi_dNoSuchInterface = -112;
static const int mi_dUnknownSelector = -113;
/* Limits */
#define MI_D_MAX_CHANNELS 16 /* Max. Standard MIDI Channels */
#define MI_D_MAX_INTERFACE_NAME_LENGTH 64 /* Max. Interface C String Length */
#define MI_D_MAX_CLIENT_NAME_LENGTH 32 /* Max. Client C String Length */
#define MI_D_MESSAGE_BUFFER_LENGTH 80 /* Length of Message Printout */
#define MI_D_SYSEX_BUFFER_LINE_LENGTH 68 /* Line Length of Sysex Printout */
/* ===========================================================================
*
* mi_dVersion
*/
/*
* mi_dVersion
* -----------
* Return the Mi_D version number. This number is a 4-byte quantity with
* the major version (M), minor version (m) and release number (r) in the
* most significant three bytes and the release status (s) and number (n) in
* the least significant byte:
*
* 0xMMmmrrsn
*
* s may be one of
*
* 8 final release
* 4 beta release
* 2 alpha release
* 1 development release
*
* and n denotes the serial number of the given release. M, m and r are
* binary-decimal-coded. For example,
*
* 0x01170443
*
* translates to version 1.17.4, beta 3.
*
* Arguments:
*
*
* Result:
* unsigned long version
*
* See: mi_d.c++
*/
#ifdef __cplusplus
extern "C"
#endif
unsigned long mi_dVersion(void);
/* ===========================================================================
*
* Opening/Closing MIDI
*
*
* mi_dOpen
* --------
* Initialize MIDI environment and scheduler, open the driver and start the
* timer. Calling mi_dOpen when MIDI is already open closes MIDI first, then
* re-opens it again.
*
* OMS NOTE: No provisions are made at to specify custom client and port
* signatures. Rather, Mi_D generates signatures on the basis of the system
* clock. More precisely, the client, input port, and output port
* signatures will be `edXX' (that is, "Mi_D" spelled out in modern
* pitches), `->XX', and `<-XX', respectively, where `XX' represents the
* mentioned 2-byte quantity derived from the system clock.
*
* Arguments:
* clientName client namestring (truncated to
* MI_D_MAX_CLIENT_NAME_LENGTH characters)
* maxLChannels maximum number of logical channels
* maxRoutes maximum number of routes
* maxConnections maximum number of connections
* maxMappings maximum number of mappings (for both, routes and
* logical channels)
* queueSize size of the MIDI output queue (in Events)
*
* Result:
* mi_dNoErr success
* mi_dErr driver-related failure
* mi_dOutOfMemory not enough memory to initialize environment,
* driver or scheduler
*
* See: mi_d.c++
*/
extern char mi_dClientName[]; /* Default client name ("Mi_D") */
#ifdef __cplusplus
extern "C"
int mi_dOpen(const char* clientName = mi_dClientName,
const unsigned short maxLChannels = 100,
const unsigned short maxRoutes = 10,
const unsigned short maxConnections = 10,
const unsigned int maxMappings = 400,
const unsigned int queueSize = 2000);
#else
int mi_dOpen(const char* clientName,
const unsigned short maxLChannels,
const unsigned short maxRoutes,
const unsigned short maxConnections,
const unsigned int maxMappings,
const unsigned int queueSize);
#endif
/*
* mi_dClose
* ---------
* Close the driver, free environment and scheduler data. It is safe to
* call mi_dClose at any time.
*
* Arguments:
*
*
* Result:
*
*
* See: mi_d.c++
*/
#ifdef __cplusplus
extern "C"
#endif
void mi_dClose(void);
/* ===========================================================================
*
* Environment
*
*
* mi_dUpdateSystemInfo
* --------------------
* Update environment information pertaining to the system interfaces. This
* function is called automatically by mi_dOpen, mi_dGetEnvironmentInfo and
* mi_dPrintEnvironment. Clients may want to call mi_dUpdateSystemInfo when
* their driver-side MIDI setup changed and if they experience MIDI
* transmission problems that may be related to missing interfaces.
*
* Arguments:
*
*
* Result:
* mi_dNoErr success
* mi_dErr an unexpected error occured
* mi_dOutOfMemory not enough memory to store interface namestrings
* mi_dNoInterfaces the system has no interfaces defined
* mi_dEnvChanged the system environment has changed (this is not
* an error)
*
* See: environment.c++
*/
#ifdef __cplusplus
extern "C"
#endif
int mi_dUpdateSystemInfo(void);
/*
* mi_dPrintEnvironment
* --------------------
* Print current environment information. A verbosity level of 0 prints a
* summary only, level 1 prints the contents of the channel and route maps,
* and level 2 prints also their inverse maps.
*
* Arguments:
* stream stream to print to; if 1 or 2 are passed instead
* of a FILE*, print to stdout or stderr, respectively
* verbosity verbosity level: 0, 1, or 2
*
* Result:
* mi_dNoErr success
* mi_dErr failure
*
* See: environment.c++
*/
#ifdef __cplusplus
extern "C"
int mi_dPrintEnvironment(FILE* stream = stderr, const int verbosity = 0);
#else
int mi_dPrintEnvironment(FILE* stream, const int verbosity);
#endif
/*
* mi_dGetEnvironmentInfo
* ----------------------
* Return specific bits of information about the MIDI environment. This
* function is provided for clients who want access to environment data
* other than a simple print-out. Any arbitrary collection of data may be
* specified, and will be returned, using a client-side array of mi_dInfo
* structures:
*/
typedef struct {
int param; /* Environment info selector */
union { /* Result (type depends on selector) */
unsigned int ui;
const void* ptr;
} val;
int err; /* Status: mi_dNoErr or mi_dUnknownSelector */
} mi_dInfo;
/*
* whose selector field contains upon entry one of:
*/
enum mi_dInfoSelector { /* Result Type: */
mi_dMaxLogicalChannels = 0, /* unsigned int */
mi_dMaxRoutes = 1, /* unsigned int */
mi_dMaxConnections = 2, /* unsigned int */
mi_dMaxMapCells = 3, /* unsigned int */
mi_dMapCellsInUse = 4, /* unsigned int */
mi_dQueueSize = 5, /* unsigned int */
mi_dNrOfInterfaces = 6, /* unsigned int */
mi_dInterfaceInfo = 7, /* mi_dInterface* (*)[] */
mi_dInputInterfaces = 8, /* mi_dInterface* (*)[] */
mi_dOutputInterfaces = 9, /* mi_dInterface* (*)[] */
mi_dChannelMap = 10, /* mi_dMapCell* (*)[] */
mi_dInvChannelMap = 11, /* mi_dMapCell* (*)[][MI_D_MAX_CHANNELS] */
mi_dRouteMap = 12, /* mi_dMapCell* (*)[] */
mi_dInvRouteMap = 13 /* mi_dMapCell* (*)[] */
};
#define MI_D_NR_OF_INFO_SELECTORS 14 /* Utility Constant */
/*
* Upon return, the result will be stored in either the val.ui or val.ptr
* fields, depending on the selector's result type, as indicated above. The
* err field will be set to mi_dUnknownSelector in the event of an error, or
* to mi_dNoErr otherwise.
*
* DATA STRUCTURES
*
* The mi_dInterfaceInfo, mi_dInputInterfaces, and mi_dOutputInterfaces
* selectors return each arrays of pointers to mi_dInterface structures
* holding the interface's name and direction. Interface name strings are
* system-dependent and will always be truncated to
* MI_D_MAX_INTERFACE_NAME_LENGTH characters. The direction field indicates
* whether the interface is an input, output, or bidirectional interface.
*
* The array retrieved through the mi_dInterfaceInfo selector lists the
* all interfaces present in the system, in some system-dependend order.
* Its length is thus identical to the value retrieved using the
* mi_dNrOfInterfaces selector. The arrays returned in response to the
* mi_dInputInterfaces and mi_dOutputInterfaces selectors represent
* associations between connections and interfaces and thus have a length
* equal to the value retrieved through the mi_dMaxConnections selector. A
* NULL pointer indicates that the connection is not associated with an
* interface.
*/
typedef struct {
char name[MI_D_MAX_INTERFACE_NAME_LENGTH];
int direction; /* mi_dInput, mi_dOutput, or mi_dBidirectional */
} mi_dInterface;
/*
* The mi_dChannelMap, mi_dInvChannelMap, mi_dRouteMap, and mi_dInvRouteMap
* selectors return environment maps as pointers to arrays of mi_dMapCell
* structures. The size of these arrays depends on the map returned and
* should be retrieved using the mi_dMaxLogicalChannels, mi_dMaxRoutes, or
* mi_dMaxConnections selectors:
*
* * The channel map maps logical channels onto pairs of (logical) routes
* and (real) channels. Its length may therefore be retrieved using the
* mi_dMaxLogicalChannels selector
*
* * Conversely, the inverse channel map maps pairs of routes and (real)
* channels onto logical channels and is thus a two-dimensional array
* of MI_D_MAX_CHANNELS columns and a number of rows as returned by the
* mi_dMaxRoutes selector
*
* * Similarly, the route map translates from (logical) routes to (real)
* connections and thus also has a length as retrieved by the
* mi_dMaxRoutes selector, whereas
*
* * The inverse route map translates from (real) connections to (logical)
* routes and has a length as retrieved by the
* mi_dMaxConnections selector.
*
* Each mi_dMapCell holds exactly one mapping (a structure of type
* mi_dMapping) specifying either the logical channel, a pair consisting of
* a route and a channel (a structure of type mi_dRoutedChannel), the route,
* or the connection the current value should be translated into.
*
* Finally, since Mi_D supports many-to-many mappings in each translation
* table, several mi_dMapCell structures may be chained together via their
* field to form a linked list.
*/
typedef struct { /* "routed" channel specification */
unsigned short route;
unsigned short chan;
} mi_dRoutedChannel;
typedef union {
unsigned short lchan; /* logical channel */
mi_dRoutedChannel rchan; /* "routed" channel */
unsigned short conn; /* connection */
unsigned short route; /* route */
} mi_dMapping;
typedef struct mi_dMapCell {
mi_dMapping val;
struct mi_dMapCell* next;
} mi_dMapCell;
/*
*
* Arguments:
* morsels array of mi_dInfo structures
* n number of mi_dInfo structures to fill
*
* Result:
* mi_dNoErr success
* mi_dErr the environment is uninitialized
*
* See: environment.c++
*/
#ifdef __cplusplus
extern "C"
#endif
int mi_dGetEnvironmentInfo(mi_dInfo morsels[], unsigned int n);
/*
* mi_dCheckEnvironment
* --------------------
* Check the consistency of the various maps in the MIDI environment. This
* function does not check whether connections are actually associated with
* interfaces, since it is explicitly allowed to have connections
* "dangling".
*
* If mi_dErr is returned, mi_dPrintEnvironment or mi_dGetEnvironmentInfo
* may be used to get a more detailed description of the inconsistencies
* encountered.
*
* Arguments:
*
*
* Result:
* mi_dNoErr environment is consistent
* mi_dErr environment is inconsistent
*
* See: environment.c++
*/
#ifdef __cplusplus
extern "C"
#endif
int mi_dCheckEnvironment(void);
/*
* mi_dAddChanmapMapping, mi_dClearChanmapMapping
* ----------------------------------------------
* Add (or clear) a mapping from a logical channel to a route and (real)
* channel and vice versa to (or from) the environment's channel map.
*
* Arguments:
* lchan logical channel number
* route (logical) route number
* chan (real) channel number
*
* Result:
* mi_dNoErr success
* mi_dIllegalValue an argument was out of range (see mi_dOpen)
* mi_dOutOfMemory no more mi_dMapCells available
* mi_dNullHandle the specified mapping did not exist
*
* See: environment.c++
*/
#ifdef __cplusplus
extern "C" {
#endif
int mi_dAddChanmapMapping(const unsigned short lchan,
const unsigned short route,
const unsigned short chan);
int mi_dClearChanmapMapping(const unsigned short lchan,
const unsigned short route,
const unsigned short chan);
#ifdef __cplusplus
}
#endif
/*
* mi_dClearChanmap
* ----------------
* Clear all channel map entries.
*
* Arguments:
*
*
* Result:
*
*
* See: environment.c++
*/
#ifdef __cplusplus
extern "C"
void mi_dClearChanmap(void);
#endif
/*
* mi_dAddRoutemapMapping, mi_dClearRoutemapMapping
* ------------------------------------------------
* Add (or clear) a mapping from a route to a connection and vice versa to
* (or from) the environment's route map.
*
* Arguments:
* route (logical) route number
* conn (real) connection number
*
* Result:
* mi_dNoErr success
* mi_dIllegalValue an argument was out of range
* mi_dOutOfMemory no more mi_dMapCells available
* mi_dNullHandle the specified mapping did not exist
*
* See: environment.c++
*/
#ifdef __cplusplus
extern "C" {
#endif
int mi_dAddRoutemapMapping(const unsigned short route,
const unsigned short conn);
int mi_dClearRoutemapMapping(const unsigned short route,
const unsigned short conn);
#ifdef __cplusplus
}
#endif
/*
* mi_dClearRoutemap
* -----------------
* Clear all route map entries.
*
* Arguments:
*
*
* Result:
*
*
* See: environment.c++
*/
#ifdef __cplusplus
extern "C"
#endif
void mi_dClearRoutemap(void);
/*
* mi_dStandardMaps
* ----------------
* Map 16 logical channels onto route 0, channels 0-15, and 1 route onto
* connection 0. This provides a simple, one-connection, 16-channel
* Standard MIDI environment. It does not, however, associate an actual
* interface with the connection, since there is no standard way of doing
* so. Call mi_dConnect to associate an interface and thus make the actual
* input and output connections.
*
* Arguments:
*
*
* Result:
* mi_dNoErr success
* mi_dErr environment does not allow for either 16 channels,
* 1 route or doesn't have enough mi_dMapCells (see
* mi_dOpen)
*
* See: environment.c++
*/
#ifdef __cplusplus
extern "C"
#endif
int mi_dStandardMaps(void);
/*
* mi_dConnect
* -----------
* Associate or dissociate a named interface with a connection. The
* operation may apply to either the input, output, or both associations.
*
* Arguments:
* conn connection to associate with interface
* name interface name to associate with connection
* ;if NULL, clear (dissociate) an existing
* association
* direction mi_dInput, mi_dOutput, or mi_dBidirectional
*
* Result:
* mi_dNoErr success
* mi_dErr failure
* mi_dUndefinedFlag was not mi_dInput, mi_dOutput, or
* mi_dBidirectional
* mi_dNoSuchInterface is not a known interface namestring
*
* See: environment.c++
*/
/* Interface Direction Flags */
static const int mi_dInput = 1;
static const int mi_dOutput = 2;
static const int mi_dBidirectional = 3; /* mi_dInput | mi_dOutput */
#ifdef __cplusplus
extern "C"
#endif
int mi_dConnect(const unsigned short conn,
const char* name,
const int direction);
/* ===========================================================================
*
* I/O
*
*
* *******************************************************************
* *******************************************************************
*
* WARNING: for performance reasons, the output routines do not test
* whether the environment is valid and hence will cause a
* segmentation violation if called with midi closed.
*
* DO NOT CALL ANY OF THESE ROUTINES WITHOUT HAVING OPENED MIDI FIRST!
*
* *******************************************************************
* *******************************************************************
*
* MIDI Message Formats
* ====================
*
* Mi_D's API supports two MIDI message formats. Routines ending in "_3c"
* pass messages as three (unsigned) char's, i.e. a status byte and two data
* bytes, whereas routines ending in "_el" pass the message as one single
* unsigned long in encoded format (see below). MIDI sysex data are stored
* and sent as strings. Running status is not used.
*
* Standard MIDI messages are passed as three separate bytes, a status byte
* and two data bytes, along with an (unsigned) I/O specification
* representing the messages route (system messages) or logical channel
* (channel messages). The channel field (the lower 4 bits of the status
* byte in channel messages) is ignored on output and cleared on input.
*
* STANDARD MESSAGES
* -----------------------------------------------
* 31.. ..24 .... ..16 .... ...8 .... ...0 (bits)
*
* system messages:
* ---- ---- ---- ---- route (unsigned short)
* 1--- ---- Status
* 0--- ---- Data Byte 1 (default: 0x00)
* 0--- ---- Data Byte 2 (default: 0x00)
* channel messages:
* ---- ---- ---- ---- logical channel (unsigned short)
* 1--- 0000 Status
* 0--- ---- Data Byte 1 (default: 0x00)
* 0--- ---- Data Byte 2 (default: 0x00)
*
*
* Encoded MIDI messages pack the status byte and (up to two) data bytes of
* a standard MIDI message into the lower 21 bits of an unsigned long. The
* remaining bits (22-31) are used to hold logical channel/routing
* information. The nibbles of the status byte are swapped in order to
* allow the 4 bits channel information present in the lower nibble of the
* status byte of channel messages to form a contiguous field with bits
* 22-31. As a result (and assuming 32-bit ints), channel messages have 14
* bits (bits 18-31) to represent a logical channel from 0 to 16384 whereas
* system messages use up to 10 bits (bits 22-31) to represent (logical)
* routes ranging from 0 to 1024.
*
* ENCODED MESSAGES
* -----------------------------------------------
* 31.. ..24 .... ..16 .... ...8 .... ...0 (bits)
*
* system message fields:
* ---- ---- -- mi_dEncRouteByte
* -- -- mi_dEncLStatusByte
* 1- -- mi_dEncUStatusByte
* -- --1- -- mi_dEncSwappedStatusByte
* -- ---- - mi_dEncData1Byte
* --- ---- mi_dEncData2Byte
* channel message subfields:
* ---- ---- ---- -- mi_dEncLChannelByte
* 1- -- mi_dEncOpcodeByte
*/
/* Bit masks and offsets (Encoded MIDI Messages) */
static const unsigned long mi_dEncRouteByte = 0xffc00000UL;
static const unsigned long mi_dEncLStatusByte = 0x003c0000UL;
static const unsigned long mi_dEncUStatusByte = 0x0003c000UL;
static const unsigned long mi_dEncSwappedStatusByte = 0x003fc000UL;
static const unsigned long mi_dEncLChannelByte = 0xfffc0000UL;
static const unsigned long mi_dEncOpcodeByte = 0x0003c000UL;
static const unsigned long mi_dEncData1Byte = 0x00003f80UL;
static const unsigned long mi_dEncData2Byte = 0x0000007fUL;
static const unsigned int mi_dEncRouteOffs = 22;
static const unsigned int mi_dEncUStatusOffs = 10; /* byte-aligned */
static const unsigned int mi_dEncLStatusOffs = 18;
static const unsigned int mi_dEncSwappedStatusOffs = 14;
static const unsigned int mi_dEncLChannelOffs = 18;
static const unsigned int mi_dEncOpcodeOffs = 10; /* byte-aligned */
static const unsigned int mi_dEncData1Offs = 7;
static const unsigned int mi_dEncData2Offs = 0;
/* AND with this mask to turn an encoded note on message into a note off */
/* message with zero velocity. */
static const unsigned long mi_dEncNoteOffMask = 0xfffe3f80U;
/*
* mi_dWriteMessage_3c/el
* ----------------------
* Send a message. Messages may either be sent as (logical) output plus
* three individual bytes (mi_dWriteMessage_3c) or as an encoded long
* containing (logical) output specification according to the format
* detailed above (mi_dWriteMessage_el). System messages output on
* (logical) routes, channel messages on logical channels.
*
* Arguments:
* output logical channel or route (depending on message
* type)
* status status byte (bits 0-3 are ignored in channel
* messages)
* data1 data byte 1
* data2 data byte 2
* message message in encoded format
* time time stamp (in ms)
*
* Result:
* mi_dNoErr success
* mi_dErr a logical channel or route could not be resolved
*
* See: mi_d.c++
*/
#ifdef __cplusplus
extern "C" {
#endif
int mi_dWriteMessage_3c(const unsigned short output,
const char status,
const char data1,
const char data2,
const unsigned long time);
int mi_dWriteMessage_el(const unsigned long message,
const unsigned long time);
#ifdef __cplusplus
}
#endif
/*
* mi_dWriteSysex
* --------------
*
* Send a sysex message. The sysex message is stored in a block of memory
* pointed to by whose length (in bytes) is stored in . It
* is generally the client's responsibility not to deallocate before
* the last message pointing to it has been written out. (Note, too, that the
* last message written out is not necessarily the last scheduled message!)
* That is, unless the client stores sysex both, as constant data and in
* static memory, it needs to know when it is safe to dispose of old data.
* This issue arises not only if (dynamic) sysex data is scheduled for
* future output, but also (due to latencies inherent in the scheduler,
* driver and OS) if it is to be output immediately. Hence, unless the
* client stores sysex data statically, it is recommended that it stores
* along with the sysex message an unsigned long value and passes its
* address as . The long should be cleared initially.
* mi_dWriteSysex then increments this value when the sysex message is
* queued and decrements it after it has been written out. The client
* should examine its value before every attempt to release the data and
* only do so if it is again equal to zero. Note that this mechanism
* requires that the client consistently passes the same address in
* in case it writes a sysex message multiple times in a row.
*
* NOTE: Watch out for languages with automatic garbage collection! E.g.,
* the LISP call
*
* (let ((sysex (make-c-array ...)))
* (mi_d:write-sysex sysex (+ (mi_d:get-time) 100)))
*
* could be subject to garbage collection as soon as the "let" form returns.
*
*
* Arguments:
* route (logical) route to output the message on
* length length of data in bytes
* sysex string holding a complete sysex message (including
* the F7/F0 markers)
* time time stamp (in ms)
* refCount pointer to storage used as data reference counter
*
* Result:
* mi_dNoErr success
* mi_dErr a logical channel or route could not be resolved
*
* See: mi_d.c++
*/
#ifdef __cplusplus
extern "C"
int mi_dWriteSysex(const unsigned short route,
const unsigned int length,
const unsigned char* data,
const unsigned long time,
unsigned long* refcounter = NULL);
#else
int mi_dWriteSysex(const unsigned short route,
const unsigned int length,
const unsigned char* data,
const unsigned long time,
unsigned long* refcounter);
#endif
/*
* mi_dWriteNote_3c/el
* -------------------
* Convenience routine to schedule note-on and note-off messages in pairs.
* A message is either a logical channel followed by three individual bytes
* specifying the key and both velocities (mi_dWriteNote_3c), or an encoded
* note-on message according to the format detailed above
* (mi_dWriteNote_el). Both functions take a duration and time parameter.
*
* Arguments:
* lchan logical channel
* key MIDI key number
* onVelocity key velocity for the note-on message
* offVelocity key velocity for the note-off message
* onMessage note-on message in encoded format
* duration duration of the note (in ms)
* time time stamp (in ms)
*
* Result:
* mi_dNoErr success
* mi_dErr a logical channel or route could not be resolved
*
* See: mi_d.c++
*/
#ifdef __cplusplus
extern "C" {
#endif
int mi_dWriteNote_3c(const unsigned short lchan,
const char key,
const char onVelocity,
const char offVelocity,
const unsigned long duration,
const unsigned long time);
int mi_dWriteNote_el(const unsigned long onMessage,
const char offVelocity,
const unsigned long duration,
const unsigned long time);
#ifdef __cplusplus
}
#endif
/*
* mi_dReadMessages_3c/el
* ----------------------
* Receive all MIDI events that arrived since this function has been
* called last (or since MIDI has been opened or input has been flushed).
* The incoming events are placed in an input queue and may be retrieved
* using the corresponding mi_dInputMessage_3c/el calls below. The client
* may switch between the 3c and el forms of these routines any time
* mi_dReadMessages_3c/el is called, that is, it is only required that the
* mi_dInputMessage_3c/el calls be consistent with the last call to
* mi_dReadMessages_3c/el.
*
* Note that reception of MIDI messages is subject to availability, request
* and input buffer storage space. That is, incoming messages are lost
* unless requested in time before the buffer overruns and mi_dReadMessages
* returns zero without blocking if no messages are available.
*
* Arguments:
*
*
* Result:
* int the number of MIDI events read
* mi_dErr driver-side failure
*
* See: mi_d.c++
*/
#ifdef __cplusplus
extern "C" {
#endif
int mi_dReadMessages_3c(void);
int mi_dReadMessages_el(void);
#ifdef __cplusplus
}
#endif
/*
* mi_dInputMessage_3c/el, mi_dInputSysex
* --------------------------------------
* Return components of an input event. MIDI messages other than System
* Exclusive messages may be retrieved either as individual bytes in
* standard format or as one message in encoded format. If the message is a
* sysex message, will be set to 0xF0 (mi_dInputMessage_3c) or the
* encoded status byte to 0xF0 (mi_dInputMessage_el). mi_dInputSysex may
* then be used to retrieve a pointer to the sysex data, whose length is
* stored in . Since the input queue is ring buffered, the client
* should copy the data as soon as possible in order to prevent data loss
* due to buffer overruns or other incoming sysex messages. Note that sysex
* data is NOT copied if MIDI input data is multicasted or multiplexed in
* the environment. Instead, all (strictly sequential) input events
* retrieved by the same call to mi_dReadMessages share the same sysex data
* block and the client can avoid copying the same data over and over again
* by comparing each pointer with the pointer the immediately previous
* event. A sysex data block whose first byte is NOT 0xF0 is invalid (i.e.,
* has most likely been overrun).
*
* Arguments:
* i message index; must be less than the number of
* messages read as returned by the last call to
* mi_dReadMessages
* input storage for route or logical channel of the message
* status storage for status byte
* data1 storage for data byte 1
* data2 storage for data byte 2
* message storage for encoded message
* time storage for time stamp
* sysex storage for pointer to sysex data
* length storage for length of sysex data
*
* Result:
* mi_dNoErr success
* mi_dErr message at index is not a sysex message
* mi_dOutOfBounds was larger than the result of the last call to
* mi_dReadMessages_3c/el
*
* See: mi_d.c++
*/
#ifdef __cplusplus
extern "C" {
#endif
int mi_dInputMessage_3c(const unsigned int i,
unsigned short* input,
unsigned char* status,
unsigned char* data1,
unsigned char* data2,
unsigned long* time);
int mi_dInputMessage_el(const unsigned int i,
unsigned long* message,
unsigned long* time);
int mi_dInputSysex(const unsigned int i,
const unsigned char** sysex,
unsigned int* length);
#ifdef __cplusplus
}
#endif
/* ===========================================================================
*
* Flushing
*
*
* mi_dFlushInput, mi_dFlushOutput
* -------------------------------
* Flush pending input or output.
*
* Arguments:
*
*
* Result:
*
*
* See: mi_d.c++
*/
#ifdef __cplusplus
extern "C" {
#endif
void mi_dFlushInput(void);
void mi_dFlushOutput(void);
#ifdef __cplusplus
}
#endif
/*
* mi_dAllNotesOff
* ---------------
* Broadcast All-Notes-Off, All-Sound-Off, and Reset-All-Controllers control
* messages on all active output connections. Note that this does not work
* with some older MIDI devices that are unaware of these messages, these
* devices continue to need Note-Off messages on every channel and key number.
*
* Arguments:
*
*
* Result:
*
*
* BUGS: mi_dAllNotesOff uses control messages for
* efficiency. Mi_D currently does not provide a
* "traditional" version of this routine.
*
* See: environment.c++
*/
#ifdef __cplusplus
extern "C"
#endif
void mi_dAllNotesOff(void);
/*
* mi_dHush
* --------
* mi_dAllNotesOff followed by mi_dFlushOutput and mi_dFlushInput.
*
* Arguments:
*
*
* Result:
*
*
* See: mi_d.c++
*/
#ifdef __cplusplus
extern "C"
#endif
void mi_dHush(void);
/* ===========================================================================
*
* Timing Functions
*
*
* mi_dStartTimer, mi_dStopTimer
* -----------------------------
* Start or stop the timer used by the system. Starting it resets the time to
* zero. This is normally done automatically during mi_dOpen, but the timer
* may be restarted anytime, whether it has been previously stopped using
* mi_dStopTimer or not. mi_dStopTimer is a no-op and provided for backwards
* compatibility.
*
* Arguments:
*
*
* Result:
* mi_dNoErr mi_dStartTimer and mi_dStopTimer always return
* successfully
*
* See: .c++
*/
#ifdef __cplusplus
extern "C" {
#endif
int mi_dStartTimer(void);
int mi_dStopTimer(void);
#ifdef __cplusplus
}
#endif
/*
* mi_dGetTime, mi_dSetTime
* ------------------------
* Get or set the current time (in ms). Calling mi_dSetTime does not
* interrupt the timer but rather sets an internal offset that is used to
* calculate time.
*
* Arguments:
* time value to set the current time to
*
* Result:
* unsigned long mi_dGetTime returns the current time in ms
* mi_dNoErr mi_dSetTime returns always mi_dNoErr
*
* See: .c++
*/
#ifdef __cplusplus
extern "C" {
#endif
unsigned long mi_dGetTime(void);
int mi_dSetTime(const unsigned long time);
#ifdef __cplusplus
}
#endif
/* ===========================================================================
*
* Utilities
*/
/*
* mi_dPrintMessage_3c, mi_dPrintMessage_el, mi_dPrintSysexData
* ------------------------------------------------------------
* Print an (encoded or unencoded) message; print a sysex message.
*
* Arguments:
* stream if not NULL, stream to print to; if 1 or 2 are
* passed instead of a FILE*, print to stdout or
* stderr, respectively
* buf if not NULL, buffer to print to; has to be
* at least MI_D_MESSAGE_BUFFER_LENGTH in size for
* standard messages;
* ioref logical channel or route (depending on message
* type)
* status status byte (bits 0-3 are ignored in channel
* messages)
* data1 data byte 1
* data2 data byte 2
* message message in encoded format
* time time stamp (in ms)
* lines print up to lines of sysex data; if
* printing to , has to be at least of size
* * MI_D_SYSEX_BUFFER_LINE_LENGTH bytes; if
* contains more bytes than fit in
* lines, the last line will print a message
* indicating the amount of bytes remaining in the
* message; setting to 0 always prints the
* full message
* data pointer to a block of sysex data
* length length of sysex data in bytes
*
* Result:
* mi_dNoErr success
* mi_dErr a logical channel or route could not be resolved
*
* See: mi_d.c++
*/
#ifdef __cplusplus
extern "C" {
#endif
void mi_dPrintMessage_3c(FILE* stream,
char* buf,
const unsigned short ioref,
const unsigned char status,
const unsigned char data1,
const unsigned char data2,
const unsigned long time);
void mi_dPrintMessage_el(FILE* stream,
char* buf,
const unsigned long message,
const unsigned long time);
void mi_dPrintSysexData(FILE* stream,
char* buf,
const unsigned int lines,
const unsigned char* data,
const unsigned int length);
#ifdef __cplusplus
}
#endif
/*
* mi_dGetErrorString
* ------------------
* Return the string corresponding to a Mi_D result code. A generic string
* is returned in case of an unrecognized result code, along with its
* numerical value. The client should deal with the string before calling
* mi_dGetErrorString again, since another unrecognized result code will
* cause mi_dGetErrorString to overwrite the old string.
*
* Arguments:
* code result code
*
* Result:
* char* string corresponding to the result code
*
* See: mi_d.c++
*/
#ifdef __cplusplus
extern "C"
#endif
const char* mi_dGetErrorString(const int code);
/* ===========================================================================
*
* Platform-Specific Functions
*/
#if defined(OMS)
/*
* mi_dOMSOpenCurStudioSetup, mi_dOMSOpenMIDISetupDialog
* -----------------------------------------------------
* Open the current OMS Studio Setup or OMS MIDI Setup dialog,
* respectively. OMS only.
*
* Arguments:
*
*
* Result:
*
*
* See: oms-midi.c++
*/
#ifdef __cplusplus
extern "C" {
#endif
void mi_dOMSOpenCurStudioSetup(void);
void mi_dOMSOpenMIDISetupDialog(void);
#ifdef __cplusplus
}
#endif
#endif /* defined(OMS) */
#endif /* MI_D_H */
/*
* EOF
*/