PortMidi
Cross-platform MIDI IO library
portmidi.h
1#ifndef PORT_MIDI_H
2#define PORT_MIDI_H
3#ifdef __cplusplus
4extern "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
100typedef enum {
102 pmNoData = 0,
107 pmHostError = -10000,
113 pmInsufficientMemory,
114 pmBufferTooSmall,
115 pmBufferOverflow,
116 pmBadPtr,
121 pmInternalError,
126 /* NOTE: If you add a new error type, you must update Pm_GetErrorText(). */
142PMEXPORT PmError Pm_Initialize(void);
143
148PMEXPORT PmError Pm_Terminate(void);
149
151typedef void PortMidiStream;
152
154#define PmStream PortMidiStream
155
166PMEXPORT int Pm_HasHostError(PortMidiStream * stream);
167
168
173PMEXPORT const char *Pm_GetErrorText(PmError errnum);
174
179PMEXPORT void Pm_GetHostErrorText(char * msg, unsigned int len);
180
182#define PM_HOST_ERROR_MSG_LEN 256u
183
189typedef int PmDeviceID;
190
195#define pmNoDevice -1
196
200#define PM_DEVICEINFO_VERS 200
201typedef struct {
203 const char *interf;
205 char *name;
206 int input;
207 int output;
208 int opened;
211
213PMEXPORT int Pm_CountDevices(void);
214
309
312
316typedef int32_t PmTimestamp;
317typedef PmTimestamp (*PmTimeProcPtr)(void *time_info);
318
320#define PmBefore(t1,t2) ((t1-t2) < 0)
337PMEXPORT const PmDeviceInfo *Pm_GetDeviceInfo(PmDeviceID id);
338
378PMEXPORT PmError Pm_OpenInput(PortMidiStream** stream,
379 PmDeviceID inputDevice,
380 void *inputDriverInfo,
381 int32_t bufferSize,
382 PmTimeProcPtr time_proc,
383 void *time_info);
384
479PMEXPORT PmError Pm_OpenOutput(PortMidiStream** stream,
480 PmDeviceID outputDevice,
481 void *outputDriverInfo,
482 int32_t bufferSize,
483 PmTimeProcPtr time_proc,
484 void *time_info,
485 int32_t latency);
486
512PMEXPORT PmError Pm_CreateVirtualInput(const char *name,
513 const char *interf,
514 void *deviceInfo);
515
541PMEXPORT PmError Pm_CreateVirtualOutput(const char *name,
542 const char *interf,
543 void *deviceInfo);
544
569/* Filter bit-mask definitions */
571#define PM_FILT_ACTIVE (1 << 0x0E)
573#define PM_FILT_SYSEX (1 << 0x00)
575#define PM_FILT_CLOCK (1 << 0x08)
577#define PM_FILT_PLAY ((1 << 0x0A) | (1 << 0x0C) | (1 << 0x0B))
579#define PM_FILT_TICK (1 << 0x09)
581#define PM_FILT_FD (1 << 0x0D)
583#define PM_FILT_UNDEFINED PM_FILT_FD
585#define PM_FILT_RESET (1 << 0x0F)
587#define PM_FILT_REALTIME (PM_FILT_ACTIVE | PM_FILT_SYSEX | PM_FILT_CLOCK | \
588 PM_FILT_PLAY | PM_FILT_UNDEFINED | PM_FILT_RESET | PM_FILT_TICK)
590#define PM_FILT_NOTE ((1 << 0x19) | (1 << 0x18))
592#define PM_FILT_CHANNEL_AFTERTOUCH (1 << 0x1D)
594#define PM_FILT_POLY_AFTERTOUCH (1 << 0x1A)
596#define PM_FILT_AFTERTOUCH (PM_FILT_CHANNEL_AFTERTOUCH | \
597 PM_FILT_POLY_AFTERTOUCH)
599#define PM_FILT_PROGRAM (1 << 0x1C)
601#define PM_FILT_CONTROL (1 << 0x1B)
603#define PM_FILT_PITCHBEND (1 << 0x1E)
605#define PM_FILT_MTC (1 << 0x01)
607#define PM_FILT_SONG_POSITION (1 << 0x02)
609#define PM_FILT_SONG_SELECT (1 << 0x03)
611#define PM_FILT_TUNE (1 << 0x06)
613#define PM_FILT_SYSTEMCOMMON (PM_FILT_MTC | PM_FILT_SONG_POSITION | \
614 PM_FILT_SONG_SELECT | PM_FILT_TUNE)
615
616
617/* Set filters on an open input stream to drop selected input types.
618
619 @param stream an open MIDI input stream.
620
621 @param filters indicate message types to filter (block).
622
623 @return #pmNoError or an error code.
624
625 By default, only active sensing messages are filtered.
626 To prohibit, say, active sensing and sysex messages, call
627 Pm_SetFilter(stream, PM_FILT_ACTIVE | PM_FILT_SYSEX);
628
629 Filtering is useful when midi routing or midi thru functionality
630 is being provided by the user application.
631 For example, you may want to exclude timing messages (clock, MTC,
632 start/stop/continue), while allowing note-related messages to pass.
633 Or you may be using a sequencer or drum-machine for MIDI clock
634 information but want to exclude any notes it may play.
635 */
636PMEXPORT PmError Pm_SetFilter(PortMidiStream* stream, int32_t filters);
637
639#define Pm_Channel(channel) (1<<(channel))
640
662PMEXPORT PmError Pm_SetChannelMask(PortMidiStream *stream, int mask);
663
678PMEXPORT PmError Pm_Abort(PortMidiStream* stream);
679
696PMEXPORT PmError Pm_Close(PortMidiStream* stream);
697
723PMEXPORT PmError Pm_Synchronize(PortMidiStream* stream);
724
725
729#define Pm_Message(status, data1, data2) \
730 ((((data2) << 16) & 0xFF0000) | \
731 (((data1) << 8) & 0xFF00) | \
732 ((status) & 0xFF))
734#define Pm_MessageStatus(msg) ((msg) & 0xFF)
736#define Pm_MessageData1(msg) (((msg) >> 8) & 0xFF)
738#define Pm_MessageData2(msg) (((msg) >> 16) & 0xFF)
739
740typedef int32_t PmMessage;
806typedef struct {
807 PmMessage message;
808 PmTimestamp timestamp;
809} PmEvent;
810
844PMEXPORT int Pm_Read(PortMidiStream *stream, PmEvent *buffer, int32_t length);
845
862PMEXPORT PmError Pm_Poll(PortMidiStream *stream);
863
889PMEXPORT PmError Pm_Write(PortMidiStream *stream, PmEvent *buffer,
890 int32_t length);
891
907PMEXPORT PmError Pm_WriteShort(PortMidiStream *stream, PmTimestamp when,
908 PmMessage msg);
909
923PMEXPORT PmError Pm_WriteSysEx(PortMidiStream *stream, PmTimestamp when,
924 unsigned char *msg);
925
928#ifdef __cplusplus
929}
930#endif /* __cplusplus */
931#endif /* PORT_MIDI_H */
PMEXPORT const char * Pm_GetErrorText(PmError errnum)
Translate portmidi error number into human readable message.
Definition: portmidi.c:402
PMEXPORT PmError Pm_Initialize(void)
Pm_Initialize() is the library initialization function - call this before using the library.
Definition: portmidi.c:487
PMEXPORT PmDeviceID Pm_GetDefaultOutputDeviceID(void)
see PmDeviceID Pm_GetDefaultInputDeviceID()
PmError
PortMidi error code; a common return type.
Definition: portmidi.h:100
int PmDeviceID
Devices are represented as small integers.
Definition: portmidi.h:189
PMEXPORT PmError Pm_Terminate(void)
Pm_Terminate() is the library termination function - call this after using the library.
Definition: portmidi.c:501
PMEXPORT int Pm_CountDevices(void)
Get devices count, ids range from 0 to Pm_CountDevices()-1.
Definition: portmidi.c:315
PMEXPORT int Pm_HasHostError(PortMidiStream *stream)
Test whether stream has a pending host error.
Definition: portmidi.c:476
int32_t PmTimestamp
Represents a millisecond clock with arbitrary start time.
Definition: portmidi.h:316
PMEXPORT void Pm_GetHostErrorText(char *msg, unsigned int len)
Translate portmidi host error into human readable message.
Definition: portmidi.c:459
PMEXPORT PmDeviceID Pm_GetDefaultInputDeviceID(void)
Return the default device ID or pmNoDevice if there are no devices.
void PortMidiStream
Represents an open MIDI device.
Definition: portmidi.h:151
@ pmInterfaceNotSupported
The requested interface is not supported.
Definition: portmidi.h:124
@ pmNotImplemented
The function is not implemented, nothing was done.
Definition: portmidi.h:123
@ pmNameConflict
Cannot create virtual device because name is taken.
Definition: portmidi.h:125
@ pmGotData
A "no error" return also indicating data available.
Definition: portmidi.h:106
@ pmInvalidDeviceId
Out of range or output device when input is requested or input device when output is requested or dev...
Definition: portmidi.h:108
@ pmNoData
No error, also indicates no data available.
Definition: portmidi.h:102
@ pmNoError
Normal return value indicating no error.
Definition: portmidi.h:101
@ pmBufferMaxSize
Buffer is already as large as it can be.
Definition: portmidi.h:122
@ pmBadPtr
PortMidiStream parameter is NULL or stream is not opened or stream is output when input is required o...
Definition: portmidi.h:116
@ pmBadData
Illegal midi data, e.g., missing EOX.
Definition: portmidi.h:120
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:943
PMEXPORT const PmDeviceInfo * Pm_GetDeviceInfo(PmDeviceID id)
Get a PmDeviceInfo structure describing a MIDI device.
Definition: portmidi.c:323
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:894
PMEXPORT PmError Pm_CreateVirtualOutput(const char *name, const char *interf, void *deviceInfo)
Create a virtual output device.
Definition: portmidi.c:1047
PMEXPORT PmError Pm_DeleteVirtualDevice(PmDeviceID device)
Remove a virtual device.
Definition: portmidi.c:1053
PMEXPORT PmError Pm_CreateVirtualInput(const char *name, const char *interf, void *deviceInfo)
Create a virtual input device.
Definition: portmidi.c:1040
PMEXPORT PmError Pm_Close(PortMidiStream *stream)
Close a midi stream, flush any pending buffers if possible.
Definition: portmidi.c:1108
PMEXPORT PmError Pm_SetChannelMask(PortMidiStream *stream, int mask)
Filter incoming messages based on channel.
Definition: portmidi.c:1078
PMEXPORT PmError Pm_Abort(PortMidiStream *stream)
Terminate outgoing messages immediately.
Definition: portmidi.c:1156
PMEXPORT PmError Pm_Synchronize(PortMidiStream *stream)
(re)synchronize to the time_proc passed when the stream was opened.
Definition: portmidi.c:1141
int32_t PmMessage
see PmEvent
Definition: portmidi.h:740
PMEXPORT int Pm_Read(PortMidiStream *stream, PmEvent *buffer, int32_t length)
Retrieve midi data into a buffer.
Definition: portmidi.c:529
PMEXPORT PmError Pm_WriteSysEx(PortMidiStream *stream, PmTimestamp when, unsigned char *msg)
Write a timestamped system-exclusive midi message.
Definition: portmidi.c:752
PMEXPORT PmError Pm_Poll(PortMidiStream *stream)
Test whether input is available.
Definition: portmidi.c:569
PMEXPORT PmError Pm_WriteShort(PortMidiStream *stream, PmTimestamp when, PmMessage msg)
Write a timestamped non-system-exclusive midi message.
Definition: portmidi.c:741
PMEXPORT PmError Pm_Write(PortMidiStream *stream, PmEvent *buffer, int32_t length)
Write MIDI data from a buffer.
Definition: portmidi.c:609
Definition: portmidi.h:201
int structVersion
this internal structure version
Definition: portmidi.h:202
const char * interf
underlying MIDI API, e.g.
Definition: portmidi.h:203
char * name
device name, e.g.
Definition: portmidi.h:205
int output
true iff output is available
Definition: portmidi.h:207
int is_virtual
true iff this is/was a virtual device
Definition: portmidi.h:209
int input
true iff input is available
Definition: portmidi.h:206
int opened
used by generic PortMidi for error checking
Definition: portmidi.h:208
All midi data comes in the form of PmEvent structures.
Definition: portmidi.h:806