PortMidi
Cross-platform MIDI IO library
portmidi.h
1 #ifndef PORT_MIDI_H
2 #define PORT_MIDI_H
3 #ifdef __cplusplus
4 extern "C" {
5 #endif /* __cplusplus */
6 
7 /*
8  * PortMidi Portable Real-Time MIDI Library
9  * PortMidi API Header File
10  * Latest version available at: http://sourceforge.net/projects/portmedia
11  *
12  * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
13  * Copyright (c) 2001-2006 Roger B. Dannenberg
14  *
15  * Permission is hereby granted, free of charge, to any person obtaining
16  * a copy of this software and associated documentation files
17  * (the "Software"), to deal in the Software without restriction,
18  * including without limitation the rights to use, copy, modify, merge,
19  * publish, distribute, sublicense, and/or sell copies of the Software,
20  * and to permit persons to whom the Software is furnished to do so,
21  * subject to the following conditions:
22  *
23  * The above copyright notice and this permission notice shall be
24  * included in all copies or substantial portions of the Software.
25  *
26  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
29  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
30  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
31  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33  */
34 
35 /*
36  * The text above constitutes the entire PortMidi license; however,
37  * the PortMusic community also makes the following non-binding requests:
38  *
39  * Any person wishing to distribute modifications to the Software is
40  * requested to send the modifications to the original developer so that
41  * they can be incorporated into the canonical version. It is also
42  * requested that these non-binding requests be included along with the
43  * license above.
44  */
45 
46 /* CHANGELOG FOR PORTMIDI
47  * (see ../CHANGELOG.txt)
48  *
49  * NOTES ON HOST ERROR REPORTING:
50  *
51  * PortMidi errors (of type PmError) are generic,
52  * system-independent errors. When an error does not map to one of
53  * the more specific PmErrors, the catch-all code pmHostError is
54  * returned. This means that PortMidi has retained a more specific
55  * system-dependent error code. The caller can get more information
56  * by calling Pm_GetHostErrorText() to get a text string describing
57  * the error. Host errors can arise asynchronously from callbacks,
58  * * so there is no specific return code. Asynchronous errors are
59  * checked and reported by Pm_Poll. You can also check by calling
60  * Pm_HasHostError(). If this returns TRUE, Pm_GetHostErrorText()
61  * will return a text description of the error.
62  *
63  * NOTES ON COMPILE-TIME SWITCHES
64  *
65  * DEBUG assumes stdio and a console. Use this if you want
66  * automatic, simple error reporting, e.g. for prototyping. If
67  * you are using MFC or some other graphical interface with no
68  * console, DEBUG probably should be undefined.
69  * PM_CHECK_ERRORS more-or-less takes over error checking for
70  * return values, stopping your program and printing error
71  * messages when an error occurs. This also uses stdio for
72  * console text I/O. You can selectively disable this error
73  * checking by declaring extern int pm_check_errors; and
74  * setting pm_check_errors = FALSE; You can also reenable.
75  */
81 #include <stdint.h>
82 
83 #ifdef _WINDLL
84 #define PMEXPORT __declspec(dllexport)
85 #else
86 #define PMEXPORT
87 #endif
88 
89 #ifndef FALSE
90  #define FALSE 0
91 #endif
92 #ifndef TRUE
93  #define TRUE 1
94 #endif
95 
96 /* default size of buffers for sysex transmission: */
97 #define PM_DEFAULT_SYSEX_BUFFER_SIZE 1024
98 
99 
100 typedef enum {
101  pmNoError = 0,
102  pmNoData = 0,
106  pmGotData = 1,
107  pmHostError = -10000,
113  pmInsufficientMemory,
114  pmBufferTooSmall,
115  pmBufferOverflow,
121  pmInternalError,
126  /* NOTE: If you add a new error type, you must update Pm_GetErrorText(). */
127 } PmError;
159 PMEXPORT PmError Pm_Initialize(void);
160 
165 PMEXPORT PmError Pm_Terminate(void);
166 
168 typedef void PortMidiStream;
169 
171 #define PmStream PortMidiStream
172 
183 PMEXPORT int Pm_HasHostError(PortMidiStream * stream);
184 
185 
190 PMEXPORT const char *Pm_GetErrorText(PmError errnum);
191 
196 PMEXPORT void Pm_GetHostErrorText(char * msg, unsigned int len);
197 
199 #define PM_HOST_ERROR_MSG_LEN 256u
200 
206 typedef int PmDeviceID;
207 
212 #define pmNoDevice -1
213 
217 #define PM_DEVICEINFO_VERS 200
218 typedef struct {
220  const char *interf;
222  char *name;
223  int input;
224  int output;
225  int opened;
227 } PmDeviceInfo;
228 
230 PMEXPORT int Pm_CountDevices(void);
231 
325 PMEXPORT PmDeviceID Pm_GetDefaultInputDeviceID(void);
326 
328 PMEXPORT PmDeviceID Pm_GetDefaultOutputDeviceID(void);
329 
333 typedef int32_t PmTimestamp;
334 typedef PmTimestamp (*PmTimeProcPtr)(void *time_info);
335 
337 #define PmBefore(t1,t2) ((t1-t2) < 0)
338 
354 PMEXPORT const PmDeviceInfo *Pm_GetDeviceInfo(PmDeviceID id);
355 
395 PMEXPORT PmError Pm_OpenInput(PortMidiStream** stream,
396  PmDeviceID inputDevice,
397  void *inputDriverInfo,
398  int32_t bufferSize,
399  PmTimeProcPtr time_proc,
400  void *time_info);
401 
496 PMEXPORT PmError Pm_OpenOutput(PortMidiStream** stream,
497  PmDeviceID outputDevice,
498  void *outputDriverInfo,
499  int32_t bufferSize,
500  PmTimeProcPtr time_proc,
501  void *time_info,
502  int32_t latency);
503 
529 PMEXPORT PmError Pm_CreateVirtualInput(const char *name,
530  const char *interf,
531  void *deviceInfo);
532 
558 PMEXPORT PmError Pm_CreateVirtualOutput(const char *name,
559  const char *interf,
560  void *deviceInfo);
561 
578 PMEXPORT PmError Pm_DeleteVirtualDevice(PmDeviceID device);
586 /* Filter bit-mask definitions */
588 #define PM_FILT_ACTIVE (1 << 0x0E)
589 
590 #define PM_FILT_SYSEX (1 << 0x00)
591 
592 #define PM_FILT_CLOCK (1 << 0x08)
593 
594 #define PM_FILT_PLAY ((1 << 0x0A) | (1 << 0x0C) | (1 << 0x0B))
595 
596 #define PM_FILT_TICK (1 << 0x09)
597 
598 #define PM_FILT_FD (1 << 0x0D)
599 
600 #define PM_FILT_UNDEFINED PM_FILT_FD
601 
602 #define PM_FILT_RESET (1 << 0x0F)
603 
604 #define PM_FILT_REALTIME (PM_FILT_ACTIVE | PM_FILT_SYSEX | PM_FILT_CLOCK | \
605  PM_FILT_PLAY | PM_FILT_UNDEFINED | PM_FILT_RESET | PM_FILT_TICK)
606 
607 #define PM_FILT_NOTE ((1 << 0x19) | (1 << 0x18))
608 
609 #define PM_FILT_CHANNEL_AFTERTOUCH (1 << 0x1D)
610 
611 #define PM_FILT_POLY_AFTERTOUCH (1 << 0x1A)
612 
613 #define PM_FILT_AFTERTOUCH (PM_FILT_CHANNEL_AFTERTOUCH | \
614  PM_FILT_POLY_AFTERTOUCH)
615 
616 #define PM_FILT_PROGRAM (1 << 0x1C)
617 
618 #define PM_FILT_CONTROL (1 << 0x1B)
619 
620 #define PM_FILT_PITCHBEND (1 << 0x1E)
621 
622 #define PM_FILT_MTC (1 << 0x01)
623 
624 #define PM_FILT_SONG_POSITION (1 << 0x02)
625 
626 #define PM_FILT_SONG_SELECT (1 << 0x03)
627 
628 #define PM_FILT_TUNE (1 << 0x06)
629 
630 #define PM_FILT_SYSTEMCOMMON (PM_FILT_MTC | PM_FILT_SONG_POSITION | \
631  PM_FILT_SONG_SELECT | PM_FILT_TUNE)
632 
633 
634 /* Set filters on an open input stream to drop selected input types.
635 
636  @param stream an open MIDI input stream.
637 
638  @param filters indicate message types to filter (block).
639 
640  @return #pmNoError or an error code.
641 
642  By default, only active sensing messages are filtered.
643  To prohibit, say, active sensing and sysex messages, call
644  Pm_SetFilter(stream, PM_FILT_ACTIVE | PM_FILT_SYSEX);
645 
646  Filtering is useful when midi routing or midi thru functionality
647  is being provided by the user application.
648  For example, you may want to exclude timing messages (clock, MTC,
649  start/stop/continue), while allowing note-related messages to pass.
650  Or you may be using a sequencer or drum-machine for MIDI clock
651  information but want to exclude any notes it may play.
652  */
653 PMEXPORT PmError Pm_SetFilter(PortMidiStream* stream, int32_t filters);
654 
656 #define Pm_Channel(channel) (1<<(channel))
657 
679 PMEXPORT PmError Pm_SetChannelMask(PortMidiStream *stream, int mask);
680 
695 PMEXPORT PmError Pm_Abort(PortMidiStream* stream);
696 
713 PMEXPORT PmError Pm_Close(PortMidiStream* stream);
714 
740 PMEXPORT PmError Pm_Synchronize(PortMidiStream* stream);
741 
742 
746 #define Pm_Message(status, data1, data2) \
747  ((((data2) << 16) & 0xFF0000) | \
748  (((data1) << 8) & 0xFF00) | \
749  ((status) & 0xFF))
750 
751 #define Pm_MessageStatus(msg) ((msg) & 0xFF)
752 
753 #define Pm_MessageData1(msg) (((msg) >> 8) & 0xFF)
754 
755 #define Pm_MessageData2(msg) (((msg) >> 16) & 0xFF)
756 
757 typedef uint32_t PmMessage;
828 typedef struct {
829  PmMessage message;
830  PmTimestamp timestamp;
831 } PmEvent;
832 
866 PMEXPORT int Pm_Read(PortMidiStream *stream, PmEvent *buffer, int32_t length);
867 
884 PMEXPORT PmError Pm_Poll(PortMidiStream *stream);
885 
918 PMEXPORT PmError Pm_Write(PortMidiStream *stream, PmEvent *buffer,
919  int32_t length);
920 
936 PMEXPORT PmError Pm_WriteShort(PortMidiStream *stream, PmTimestamp when,
937  PmMessage msg);
938 
952 PMEXPORT PmError Pm_WriteSysEx(PortMidiStream *stream, PmTimestamp when,
953  unsigned char *msg);
954 
957 #ifdef __cplusplus
958 }
959 #endif /* __cplusplus */
960 #endif /* PORT_MIDI_H */
void PortMidiStream
Represents an open MIDI device.
Definition: portmidi.h:168
Buffer is already as large as it can be.
Definition: portmidi.h:122
PMEXPORT PmError Pm_Write(PortMidiStream *stream, PmEvent *buffer, int32_t length)
Write MIDI data from a buffer.
Definition: portmidi.c:619
PMEXPORT PmDeviceID Pm_GetDefaultOutputDeviceID(void)
see PmDeviceID Pm_GetDefaultInputDeviceID()
Out of range or output device when input is requested or input device when output is requested or dev...
Definition: portmidi.h:108
Normal return value indicating no error.
Definition: portmidi.h:101
PmError
PortMidi error code; a common return type.
Definition: portmidi.h:100
PMEXPORT PmError Pm_Terminate(void)
Pm_Terminate() is the library termination function - call this after using the library.
Definition: portmidi.c:511
The function is not implemented, nothing was done.
Definition: portmidi.h:123
PMEXPORT int Pm_HasHostError(PortMidiStream *stream)
Test whether stream has a pending host error.
Definition: portmidi.c:486
PMEXPORT PmError Pm_SetChannelMask(PortMidiStream *stream, int mask)
Filter incoming messages based on channel.
Definition: portmidi.c:1089
PMEXPORT PmError Pm_OpenInput(PortMidiStream **stream, PmDeviceID inputDevice, void *inputDriverInfo, int32_t bufferSize, PmTimeProcPtr time_proc, void *time_info)
Open a MIDI device for input.
Definition: portmidi.c:905
PMEXPORT PmError Pm_CreateVirtualInput(const char *name, const char *interf, void *deviceInfo)
Create a virtual input device.
Definition: portmidi.c:1051
PMEXPORT PmDeviceID Pm_GetDefaultInputDeviceID(void)
Return the default device ID or pmNoDevice if there are no devices.
PMEXPORT PmError Pm_CreateVirtualOutput(const char *name, const char *interf, void *deviceInfo)
Create a virtual output device.
Definition: portmidi.c:1058
const char * interf
underlying MIDI API, e.g.
Definition: portmidi.h:220
PMEXPORT int Pm_Read(PortMidiStream *stream, PmEvent *buffer, int32_t length)
Retrieve midi data into a buffer.
Definition: portmidi.c:539
PMEXPORT PmError Pm_WriteSysEx(PortMidiStream *stream, PmTimestamp when, unsigned char *msg)
Write a timestamped system-exclusive midi message.
Definition: portmidi.c:762
char * name
device name, e.g.
Definition: portmidi.h:222
No error, also indicates no data available.
Definition: portmidi.h:102
PMEXPORT void Pm_GetHostErrorText(char *msg, unsigned int len)
Translate portmidi host error into human readable message.
Definition: portmidi.c:469
int opened
used by generic PortMidi for error checking
Definition: portmidi.h:225
Definition: portmidi.h:218
PMEXPORT PmError Pm_Close(PortMidiStream *stream)
Close a midi stream, flush any pending buffers if possible.
Definition: portmidi.c:1119
A "no error" return also indicating data available.
Definition: portmidi.h:106
PMEXPORT const PmDeviceInfo * Pm_GetDeviceInfo(PmDeviceID id)
Get a PmDeviceInfo structure describing a MIDI device.
Definition: portmidi.c:333
PMEXPORT const char * Pm_GetErrorText(PmError errnum)
Translate portmidi error number into human readable message.
Definition: portmidi.c:412
The requested interface is not supported.
Definition: portmidi.h:124
int output
true iff output is available
Definition: portmidi.h:224
All MIDI data comes in the form of PmEvent structures.
Definition: portmidi.h:828
int32_t PmTimestamp
Represents a millisecond clock with arbitrary start time.
Definition: portmidi.h:333
int is_virtual
true iff this is/was a virtual device
Definition: portmidi.h:226
int PmDeviceID
Devices are represented as small integers.
Definition: portmidi.h:206
uint32_t PmMessage
see PmEvent
Definition: portmidi.h:757
PMEXPORT PmError Pm_OpenOutput(PortMidiStream **stream, PmDeviceID outputDevice, void *outputDriverInfo, int32_t bufferSize, PmTimeProcPtr time_proc, void *time_info, int32_t latency)
Open a MIDI device for output.
Definition: portmidi.c:954
PMEXPORT PmError Pm_Initialize(void)
Pm_Initialize() is the library initialization function - call this before using the library...
Definition: portmidi.c:497
PMEXPORT PmError Pm_WriteShort(PortMidiStream *stream, PmTimestamp when, PmMessage msg)
Write a timestamped non-system-exclusive midi message.
Definition: portmidi.c:751
PMEXPORT int Pm_CountDevices(void)
Get devices count, ids range from 0 to Pm_CountDevices()-1.
Definition: portmidi.c:325
PMEXPORT PmError Pm_Synchronize(PortMidiStream *stream)
(re)synchronize to the time_proc passed when the stream was opened.
Definition: portmidi.c:1152
Illegal midi data, e.g., missing EOX.
Definition: portmidi.h:120
PMEXPORT PmError Pm_Abort(PortMidiStream *stream)
Terminate outgoing messages immediately.
Definition: portmidi.c:1167
PMEXPORT PmError Pm_DeleteVirtualDevice(PmDeviceID device)
Remove a virtual device.
Definition: portmidi.c:1064
Cannot create virtual device because name is taken.
Definition: portmidi.h:125
int structVersion
this internal structure version
Definition: portmidi.h:219
PMEXPORT PmError Pm_Poll(PortMidiStream *stream)
Test whether input is available.
Definition: portmidi.c:579
int input
true iff input is available
Definition: portmidi.h:223
PortMidiStream parameter is NULL or stream is not opened or stream is output when input is required o...
Definition: portmidi.h:116