00001 #ifndef PORT_MIDI_H 00002 #define PORT_MIDI_H 00003 #ifdef __cplusplus 00004 extern "C" { 00005 #endif /* __cplusplus */ 00006 00007 /* 00008 * PortMidi Portable Real-Time MIDI Library 00009 * PortMidi API Header File 00010 * Latest version available at: http://sourceforge.net/projects/portmedia 00011 * 00012 * Copyright (c) 1999-2000 Ross Bencina and Phil Burk 00013 * Copyright (c) 2001-2006 Roger B. Dannenberg 00014 * 00015 * Permission is hereby granted, free of charge, to any person obtaining 00016 * a copy of this software and associated documentation files 00017 * (the "Software"), to deal in the Software without restriction, 00018 * including without limitation the rights to use, copy, modify, merge, 00019 * publish, distribute, sublicense, and/or sell copies of the Software, 00020 * and to permit persons to whom the Software is furnished to do so, 00021 * subject to the following conditions: 00022 * 00023 * The above copyright notice and this permission notice shall be 00024 * included in all copies or substantial portions of the Software. 00025 * 00026 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00027 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00028 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00029 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 00030 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 00031 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 00032 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00033 */ 00034 00035 /* 00036 * The text above constitutes the entire PortMidi license; however, 00037 * the PortMusic community also makes the following non-binding requests: 00038 * 00039 * Any person wishing to distribute modifications to the Software is 00040 * requested to send the modifications to the original developer so that 00041 * they can be incorporated into the canonical version. It is also 00042 * requested that these non-binding requests be included along with the 00043 * license above. 00044 */ 00045 00046 /* CHANGELOG FOR PORTMIDI 00047 * (see ../CHANGELOG.txt) 00048 * 00049 * NOTES ON HOST ERROR REPORTING: 00050 * 00051 * PortMidi errors (of type PmError) are generic, system-independent errors. 00052 * When an error does not map to one of the more specific PmErrors, the 00053 * catch-all code pmHostError is returned. This means that PortMidi has 00054 * retained a more specific system-dependent error code. The caller can 00055 * get more information by calling Pm_HasHostError() to test if there is 00056 * a pending host error, and Pm_GetHostErrorText() to get a text string 00057 * describing the error. Host errors are reported on a per-device basis 00058 * because only after you open a device does PortMidi have a place to 00059 * record the host error code. I.e. only 00060 * those routines that receive a (PortMidiStream *) argument check and 00061 * report errors. One exception to this is that Pm_OpenInput() and 00062 * Pm_OpenOutput() can report errors even though when an error occurs, 00063 * there is no PortMidiStream* to hold the error. Fortunately, both 00064 * of these functions return any error immediately, so we do not really 00065 * need per-device error memory. Instead, any host error code is stored 00066 * in a global, pmHostError is returned, and the user can call 00067 * Pm_GetHostErrorText() to get the error message (and the invalid stream 00068 * parameter will be ignored.) The functions 00069 * pm_init and pm_term do not fail or raise 00070 * errors. The job of pm_init is to locate all available devices so that 00071 * the caller can get information via PmDeviceInfo(). If an error occurs, 00072 * the device is simply not listed as available. 00073 * 00074 * Host errors come in two flavors: 00075 * a) host error 00076 * b) host error during callback 00077 * These can occur w/midi input or output devices. (b) can only happen 00078 * asynchronously (during callback routines), whereas (a) only occurs while 00079 * synchronously running PortMidi and any resulting system dependent calls. 00080 * Both (a) and (b) are reported by the next read or write call. You can 00081 * also query for asynchronous errors (b) at any time by calling 00082 * Pm_HasHostError(). 00083 * 00084 * NOTES ON COMPILE-TIME SWITCHES 00085 * 00086 * DEBUG assumes stdio and a console. Use this if you want automatic, simple 00087 * error reporting, e.g. for prototyping. If you are using MFC or some 00088 * other graphical interface with no console, DEBUG probably should be 00089 * undefined. 00090 * PM_CHECK_ERRORS more-or-less takes over error checking for return values, 00091 * stopping your program and printing error messages when an error 00092 * occurs. This also uses stdio for console text I/O. 00093 */ 00094 00095 #ifndef FALSE 00096 #define FALSE 0 00097 #endif 00098 #ifndef TRUE 00099 #define TRUE 1 00100 #endif 00101 00102 /* default size of buffers for sysex transmission: */ 00103 #define PM_DEFAULT_SYSEX_BUFFER_SIZE 1024 00104 00106 typedef enum { 00107 pmNoError = 0, 00108 pmNoData = 0, 00109 pmGotData = 1, 00110 pmHostError = -10000, 00111 pmInvalidDeviceId, 00116 pmInsufficientMemory, 00117 pmBufferTooSmall, 00118 pmBufferOverflow, 00119 pmBadPtr, /* PortMidiStream parameter is NULL or 00120 * stream is not opened or 00121 * stream is output when input is required or 00122 * stream is input when output is required */ 00123 pmBadData, 00124 pmInternalError, 00125 pmBufferMaxSize 00126 /* NOTE: If you add a new error type, be sure to update Pm_GetErrorText() */ 00127 } PmError; 00128 00133 PmError Pm_Initialize( void ); 00134 00139 PmError Pm_Terminate( void ); 00140 00143 typedef void PortMidiStream; 00144 #define PmStream PortMidiStream 00145 00160 int Pm_HasHostError( PortMidiStream * stream ); 00161 00162 00167 const char *Pm_GetErrorText( PmError errnum ); 00168 00173 void Pm_GetHostErrorText(char * msg, unsigned int len); 00174 00175 #define HDRLENGTH 50 00176 #define PM_HOST_ERROR_MSG_LEN 256u /* any host error msg will occupy less 00177 than this number of characters */ 00178 00185 typedef int PmDeviceID; 00186 #define pmNoDevice -1 00187 typedef struct { 00188 int structVersion; 00189 const char *interf; 00190 const char *name; 00191 int input; 00192 int output; 00193 int opened; 00195 } PmDeviceInfo; 00196 00198 int Pm_CountDevices( void ); 00241 PmDeviceID Pm_GetDefaultInputDeviceID( void ); 00243 PmDeviceID Pm_GetDefaultOutputDeviceID( void ); 00244 00249 typedef long PmTimestamp; 00250 typedef PmTimestamp (*PmTimeProcPtr)(void *time_info); 00251 00253 #define PmBefore(t1,t2) ((t1-t2) < 0) 00254 00267 const PmDeviceInfo* Pm_GetDeviceInfo( PmDeviceID id ); 00268 00333 PmError Pm_OpenInput( PortMidiStream** stream, 00334 PmDeviceID inputDevice, 00335 void *inputDriverInfo, 00336 long bufferSize, 00337 PmTimeProcPtr time_proc, 00338 void *time_info ); 00339 00340 PmError Pm_OpenOutput( PortMidiStream** stream, 00341 PmDeviceID outputDevice, 00342 void *outputDriverInfo, 00343 long bufferSize, 00344 PmTimeProcPtr time_proc, 00345 void *time_info, 00346 long latency ); 00354 /* \function PmError Pm_SetFilter( PortMidiStream* stream, long filters ) 00355 Pm_SetFilter() sets filters on an open input stream to drop selected 00356 input types. By default, only active sensing messages are filtered. 00357 To prohibit, say, active sensing and sysex messages, call 00358 Pm_SetFilter(stream, PM_FILT_ACTIVE | PM_FILT_SYSEX); 00359 00360 Filtering is useful when midi routing or midi thru functionality is being 00361 provided by the user application. 00362 For example, you may want to exclude timing messages (clock, MTC, start/stop/continue), 00363 while allowing note-related messages to pass. 00364 Or you may be using a sequencer or drum-machine for MIDI clock information but want to 00365 exclude any notes it may play. 00366 */ 00367 00368 /* Filter bit-mask definitions */ 00370 #define PM_FILT_ACTIVE (1 << 0x0E) 00371 00372 #define PM_FILT_SYSEX (1 << 0x00) 00373 00374 #define PM_FILT_CLOCK (1 << 0x08) 00375 00376 #define PM_FILT_PLAY ((1 << 0x0A) | (1 << 0x0C) | (1 << 0x0B)) 00377 00378 #define PM_FILT_TICK (1 << 0x09) 00379 00380 #define PM_FILT_FD (1 << 0x0D) 00381 00382 #define PM_FILT_UNDEFINED PM_FILT_FD 00383 00384 #define PM_FILT_RESET (1 << 0x0F) 00385 00386 #define PM_FILT_REALTIME (PM_FILT_ACTIVE | PM_FILT_SYSEX | PM_FILT_CLOCK | \ 00387 PM_FILT_PLAY | PM_FILT_UNDEFINED | PM_FILT_RESET | PM_FILT_TICK) 00388 00389 #define PM_FILT_NOTE ((1 << 0x19) | (1 << 0x18)) 00390 00391 #define PM_FILT_CHANNEL_AFTERTOUCH (1 << 0x1D) 00392 00393 #define PM_FILT_POLY_AFTERTOUCH (1 << 0x1A) 00394 00395 #define PM_FILT_AFTERTOUCH (PM_FILT_CHANNEL_AFTERTOUCH | PM_FILT_POLY_AFTERTOUCH) 00396 00397 #define PM_FILT_PROGRAM (1 << 0x1C) 00398 00399 #define PM_FILT_CONTROL (1 << 0x1B) 00400 00401 #define PM_FILT_PITCHBEND (1 << 0x1E) 00402 00403 #define PM_FILT_MTC (1 << 0x01) 00404 00405 #define PM_FILT_SONG_POSITION (1 << 0x02) 00406 00407 #define PM_FILT_SONG_SELECT (1 << 0x03) 00408 00409 #define PM_FILT_TUNE (1 << 0x06) 00410 00411 #define PM_FILT_SYSTEMCOMMON (PM_FILT_MTC | PM_FILT_SONG_POSITION | PM_FILT_SONG_SELECT | PM_FILT_TUNE) 00412 00413 00414 PmError Pm_SetFilter( PortMidiStream* stream, long filters ); 00415 00416 #define Pm_Channel(channel) (1<<(channel)) 00417 00428 PmError Pm_SetChannelMask(PortMidiStream *stream, int mask); 00429 00438 PmError Pm_Abort( PortMidiStream* stream ); 00439 00445 PmError Pm_Close( PortMidiStream* stream ); 00446 00454 #define Pm_Message(status, data1, data2) \ 00455 ((((data2) << 16) & 0xFF0000) | \ 00456 (((data1) << 8) & 0xFF00) | \ 00457 ((status) & 0xFF)) 00458 #define Pm_MessageStatus(msg) ((msg) & 0xFF) 00459 #define Pm_MessageData1(msg) (((msg) >> 8) & 0xFF) 00460 #define Pm_MessageData2(msg) (((msg) >> 16) & 0xFF) 00461 00462 typedef long PmMessage; 00528 typedef struct { 00529 PmMessage message; 00530 PmTimestamp timestamp; 00531 } PmEvent; 00532 00563 int Pm_Read( PortMidiStream *stream, PmEvent *buffer, long length ); 00564 00569 PmError Pm_Poll( PortMidiStream *stream); 00570 00584 PmError Pm_Write( PortMidiStream *stream, PmEvent *buffer, long length ); 00585 00592 PmError Pm_WriteShort( PortMidiStream *stream, PmTimestamp when, long msg); 00593 00597 PmError Pm_WriteSysEx( PortMidiStream *stream, PmTimestamp when, unsigned char *msg); 00598 00601 #ifdef __cplusplus 00602 } 00603 #endif /* __cplusplus */ 00604 #endif /* PORT_MIDI_H */