aboutsummaryrefslogtreecommitdiff
path: root/portmidi/pm_common
diff options
context:
space:
mode:
Diffstat (limited to 'portmidi/pm_common')
-rw-r--r--portmidi/pm_common/CMakeLists.txt167
-rwxr-xr-xportmidi/pm_common/pminternal.h190
-rwxr-xr-xportmidi/pm_common/pmutil.c284
-rwxr-xr-xportmidi/pm_common/pmutil.h184
-rwxr-xr-xportmidi/pm_common/portmidi.c1472
-rwxr-xr-xportmidi/pm_common/portmidi.h974
6 files changed, 3271 insertions, 0 deletions
diff --git a/portmidi/pm_common/CMakeLists.txt b/portmidi/pm_common/CMakeLists.txt
new file mode 100644
index 0000000..1ad54ad
--- /dev/null
+++ b/portmidi/pm_common/CMakeLists.txt
@@ -0,0 +1,167 @@
1# pm_common/CMakeLists.txt -- how to build portmidi library
2
3# creates the portmidi library
4# exports PM_NEEDED_LIBS to parent. It seems that PM_NEEDED_LIBS for
5# Linux should include Thread::Thread and ALSA::ALSA, but these
6# are not visible in other CMake files, even though the portmidi
7# target is. Therefore, Thread::Thread is replaced by
8# CMAKE_THREAD_LIBS_INIT and ALSA::ALSA is replaced by ALSA_LIBRARIES.
9# Is there a better way to do this? Maybe this whole file should be
10# at the parent level.
11
12# Support alternative name for static libraries to avoid confusion.
13# (In particular, Xcode has automatically converted portmidi.a to
14# portmidi.dylib without warning, so using portmidi-static.a eliminates
15# this possibility, but default for all libs is "portmidi"):
16set(PM_STATIC_LIB_NAME "portmidi" CACHE STRING
17 "For static builds, the PortMidi library name, e.g. portmidi-static.
18 Default is portmidi")
19set(PM_ACTUAL_LIB_NAME "portmidi")
20if(NOT BUILD_SHARED_LIBS)
21 set(PM_ACTUAL_LIB_NAME ${PM_STATIC_LIB_NAME})
22endif()
23
24# set the build directory for libportmidi.a to be in portmidi, not in
25# portmidi/pm_common. Must be done here BEFORE add_library below.
26if(APPLE OR WIN32)
27 set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
28 # set the build directory for .dylib libraries
29 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
30 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
31endif(APPLE OR WIN32)
32
33# we need full paths to sources because they are shared with other targets
34# (in particular pmjni). Set PMDIR to the top-level portmidi directory:
35get_filename_component(PMDIR ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
36set(PM_LIB_PUBLIC_SRC ${PMDIR}/pm_common/portmidi.c
37 ${PMDIR}/pm_common/pmutil.c
38 ${PMDIR}/porttime/porttime.c)
39add_library(portmidi ${PM_LIB_PUBLIC_SRC})
40
41# MSVCRT_DLL is "DLL" for shared runtime library, and "" for static:
42set_target_properties(portmidi PROPERTIES
43 VERSION ${LIBRARY_VERSION}
44 SOVERSION ${LIBRARY_SOVERSION}
45 OUTPUT_NAME "${PM_ACTUAL_LIB_NAME}"
46 MSVC_RUNTIME_LIBRARY
47 "MultiThreaded$<$<CONFIG:Debug>:Debug>${MSVCRT_DLL}"
48 WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
49target_include_directories(portmidi PUBLIC
50 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
51 $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
52
53
54option(PM_CHECK_ERRORS
55"Insert a check for error return values at the end of each PortMidi function.
56If an error is encountered, a text message is printed using printf(), the user
57is asked to type ENTER, and then exit(-1) is called to clean up and terminate
58the program.
59
60You should not use PM_CHECK_ERRORS if printf() does not work (e.g. this is not
61a console application under Windows, or there is no visible console on some
62other OS), and you should not use PM_CHECK_ERRORS if you intend to recover
63from errors rather than abruptly terminate the program." OFF)
64if(PM_CHECK_ERRORS)
65 target_compile_definitions(portmidi PRIVATE PM_CHECK_ERRORS)
66endif(PM_CHECK_ERRORS)
67
68macro(prepend_path RESULT PATH)
69 set(${RESULT})
70 foreach(FILE ${ARGN})
71 list(APPEND ${RESULT} "${PATH}${FILE}")
72 endforeach(FILE)
73endmacro(prepend_path)
74
75# UNIX needs pthread library
76if(NOT WIN32)
77 set(THREADS_PREFER_PTHREAD_FLAG ON)
78 find_package(Threads REQUIRED)
79endif()
80
81# Check for sndio
82if(USE_SNDIO)
83 include (FindPackageHandleStandardArgs)
84 find_path(SNDIO_INCLUDE_DIRS NAMES sndio.h)
85 find_library(SNDIO_LIBRARY sndio)
86 find_package_handle_standard_args(Sndio
87 REQUIRED_VARS SNDIO_LIBRARY SNDIO_INCLUDE_DIRS)
88endif(USE_SNDIO)
89
90# first include the appropriate system-dependent file:
91if(SNDIO_FOUND AND USE_SNDIO)
92 set(PM_LIB_PRIVATE_SRC
93 ${PMDIR}/porttime/ptlinux.c
94 ${PMDIR}/pm_sndio/pmsndio.c)
95 set(PM_NEEDED_LIBS Threads::Threads ${SNDIO_LIBRARY} PARENT_SCOPE)
96 target_link_libraries(portmidi PRIVATE Threads::Threads ${SNDIO_LIBRARY})
97 target_include_directories(portmidi PRIVATE ${SNDIO_INCLUDE_DIRS})
98elseif(UNIX AND APPLE)
99 set(Threads::Threads "" PARENT_SCOPE)
100 set(PM_LIB_PRIVATE_SRC
101 ${PMDIR}/porttime/ptmacosx_mach.c
102 ${PMDIR}/pm_mac/pmmac.c
103 ${PMDIR}/pm_mac/pmmacosxcm.c)
104 set(PM_NEEDED_LIBS
105 ${CMAKE_THREAD_LIBS_INIT}
106 -Wl,-framework,CoreAudio
107 -Wl,-framework,CoreFoundation
108 -Wl,-framework,CoreMidi
109 -Wl,-framework,CoreServices
110 PARENT_SCOPE)
111 target_link_libraries(portmidi PRIVATE
112 Threads::Threads
113 -Wl,-framework,CoreAudio
114 -Wl,-framework,CoreFoundation
115 -Wl,-framework,CoreMidi
116 -Wl,-framework,CoreServices
117 )
118 # set to CMake default; is this right?:
119 set_target_properties(portmidi PROPERTIES MACOSX_RPATH ON)
120elseif(HAIKU)
121 set(PM_LIB_PRIVATE_SRC
122 ${PMDIR}/porttime/pthaiku.cpp
123 ${PMDIR}/pm_haiku/pmhaiku.cpp)
124 set(PM_NEEDED_LIBS be midi midi2 PARENT_SCOPE)
125 target_link_libraries(portmidi PRIVATE be midi midi2)
126elseif(UNIX)
127 target_compile_definitions(portmidi PRIVATE ${LINUX_FLAGS})
128 set(PM_LIB_PRIVATE_SRC
129 ${PMDIR}/porttime/ptlinux.c
130 ${PMDIR}/pm_linux/pmlinux.c
131 ${PMDIR}/pm_linux/pmlinuxnull.c)
132 if(${LINUX_DEFINES} MATCHES ".*PMALSA.*")
133 # Note that ALSA is not required if PMNULL is defined -- PortMidi will then
134 # compile without ALSA and report no MIDI devices. Later, PMSNDIO or PMJACK
135 # might be additional options.
136 find_package(ALSA REQUIRED)
137 list(APPEND PM_LIB_PRIVATE_SRC ${PMDIR}/pm_linux/pmlinuxalsa.c)
138 set(PM_NEEDED_LIBS ${CMAKE_THREAD_LIBS_INIT} ${ALSA_LIBRARIES} PARENT_SCOPE)
139 target_link_libraries(portmidi PRIVATE Threads::Threads ALSA::ALSA)
140 set(PKGCONFIG_REQUIRES_PRIVATE "alsa" PARENT_SCOPE)
141 else()
142 message(WARNING "No PMALSA, so PortMidi will not use ALSA, "
143 "and will not find or open MIDI devices.")
144 set(PM_NEEDED_LIBS ${CMAKE_THREAD_LIBS_INIT} PARENT_SCOPE)
145 target_link_libraries(portmidi PRIVATE Threads::Threads)
146 endif()
147elseif(WIN32)
148 set(PM_LIB_PRIVATE_SRC
149 ${PMDIR}/porttime/ptwinmm.c
150 ${PMDIR}/pm_win/pmwin.c
151 ${PMDIR}/pm_win/pmwinmm.c)
152 set(PM_NEEDED_LIBS winmm PARENT_SCOPE)
153 target_link_libraries(portmidi PRIVATE winmm)
154# if(NOT BUILD_SHARED_LIBS AND PM_USE_STATIC_RUNTIME)
155 # /MDd is multithread debug DLL, /MTd is multithread debug
156 # /MD is multithread DLL, /MT is multithread. Change to static:
157# include(../pm_win/static.cmake)
158# endif()
159else()
160 message(FATAL_ERROR "Operating system not supported.")
161endif()
162
163set(PM_LIB_PUBLIC_SRC ${PM_LIB_PUBLIC_SRC} PARENT_SCOPE) # export to parent
164set(PM_LIB_PRIVATE_SRC ${PM_LIB_PRIVATE_SRC} PARENT_SCOPE) # export to parent
165
166target_sources(portmidi PRIVATE ${PM_LIB_PRIVATE_SRC})
167
diff --git a/portmidi/pm_common/pminternal.h b/portmidi/pm_common/pminternal.h
new file mode 100755
index 0000000..8b3d8f5
--- /dev/null
+++ b/portmidi/pm_common/pminternal.h
@@ -0,0 +1,190 @@
1/** @file pminternal.h header for PortMidi implementations */
2
3/* this file is included by files that implement library internals */
4/* Here is a guide to implementers:
5 provide an initialization function similar to pm_winmm_init()
6 add your initialization function to pm_init()
7 Note that your init function should never require not-standard
8 libraries or fail in any way. If the interface is not available,
9 simply do not call pm_add_device. This means that non-standard
10 libraries should try to do dynamic linking at runtime using a DLL
11 and return without error if the DLL cannot be found or if there
12 is any other failure.
13 implement functions as indicated in pm_fns_type to open, read, write,
14 close, etc.
15 call pm_add_device() for each input and output device, passing it a
16 pm_fns_type structure.
17 assumptions about pm_fns_type functions are given below.
18 */
19
20/** @cond INTERNAL - add INTERNAL to Doxygen ENABLED_SECTIONS to include */
21
22#ifdef __cplusplus
23extern "C" {
24#endif
25
26extern int pm_initialized; /* see note in portmidi.c */
27extern PmDeviceID pm_default_input_device_id;
28extern PmDeviceID pm_default_output_device_id;
29
30/* these are defined in system-specific file */
31void *pm_alloc(size_t s);
32void pm_free(void *ptr);
33
34/* if a host error (an error reported by the host MIDI API that is not
35 * mapped to a PortMidi error code) occurs in a synchronous operation
36 * (i.e., not in a callback from another thread) set these: */
37extern int pm_hosterror; /* boolean */
38extern char pm_hosterror_text[PM_HOST_ERROR_MSG_LEN];
39
40struct pm_internal_struct;
41
42/* these do not use PmInternal because it is not defined yet... */
43typedef PmError (*pm_write_short_fn)(struct pm_internal_struct *midi,
44 PmEvent *buffer);
45typedef PmError (*pm_begin_sysex_fn)(struct pm_internal_struct *midi,
46 PmTimestamp timestamp);
47typedef PmError (*pm_end_sysex_fn)(struct pm_internal_struct *midi,
48 PmTimestamp timestamp);
49typedef PmError (*pm_write_byte_fn)(struct pm_internal_struct *midi,
50 unsigned char byte, PmTimestamp timestamp);
51typedef PmError (*pm_write_realtime_fn)(struct pm_internal_struct *midi,
52 PmEvent *buffer);
53typedef PmError (*pm_write_flush_fn)(struct pm_internal_struct *midi,
54 PmTimestamp timestamp);
55typedef PmTimestamp (*pm_synchronize_fn)(struct pm_internal_struct *midi);
56/* pm_open_fn should clean up all memory and close the device if any part
57 of the open fails */
58typedef PmError (*pm_open_fn)(struct pm_internal_struct *midi,
59 void *driverInfo);
60typedef PmError (*pm_create_fn)(int is_input, const char *name,
61 void *driverInfo);
62typedef PmError (*pm_delete_fn)(PmDeviceID id);
63typedef PmError (*pm_abort_fn)(struct pm_internal_struct *midi);
64/* pm_close_fn should clean up all memory and close the device if any
65 part of the close fails. */
66typedef PmError (*pm_close_fn)(struct pm_internal_struct *midi);
67typedef PmError (*pm_poll_fn)(struct pm_internal_struct *midi);
68typedef unsigned int (*pm_check_host_error_fn)(struct pm_internal_struct *midi);
69
70typedef struct {
71 pm_write_short_fn write_short; /* output short MIDI msg */
72 pm_begin_sysex_fn begin_sysex; /* prepare to send a sysex message */
73 pm_end_sysex_fn end_sysex; /* marks end of sysex message */
74 pm_write_byte_fn write_byte; /* accumulate one more sysex byte */
75 pm_write_realtime_fn write_realtime; /* send real-time msg within sysex */
76 pm_write_flush_fn write_flush; /* send any accumulated but unsent data */
77 pm_synchronize_fn synchronize; /* synchronize PM time to stream time */
78 pm_open_fn open; /* open MIDI device */
79 pm_abort_fn abort; /* abort */
80 pm_close_fn close; /* close device */
81 pm_poll_fn poll; /* read pending midi events into portmidi buffer */
82 pm_check_host_error_fn check_host_error; /* true when device has had host */
83 /* error; sets pm_hosterror and writes message to pm_hosterror_text */
84} pm_fns_node, *pm_fns_type;
85
86
87/* when open fails, the dictionary gets this set of functions: */
88extern pm_fns_node pm_none_dictionary;
89
90typedef struct {
91 PmDeviceInfo pub; /* some portmidi state also saved in here (for automatic
92 device closing -- see PmDeviceInfo struct) */
93 int deleted; /* is this is a deleted virtual device? */
94 void *descriptor; /* ID number passed to win32 multimedia API open,
95 * coreMIDI endpoint, etc., representing the device */
96 struct pm_internal_struct *pm_internal; /* points to PmInternal device */
97 /* when the device is open, allows automatic device closing */
98 pm_fns_type dictionary;
99} descriptor_node, *descriptor_type;
100
101extern int pm_descriptor_max;
102extern descriptor_type pm_descriptors;
103extern int pm_descriptor_len;
104
105typedef uint32_t (*time_get_proc_type)(void *time_info);
106
107typedef struct pm_internal_struct {
108 int device_id; /* which device is open (index to pm_descriptors) */
109 short is_input; /* MIDI IN (true) or MIDI OUT (false) */
110 short is_removed; /* MIDI device was removed */
111 PmTimeProcPtr time_proc; /* where to get the time */
112 void *time_info; /* pass this to get_time() */
113 int32_t buffer_len; /* how big is the buffer or queue? */
114 PmQueue *queue;
115
116 int32_t latency; /* time delay in ms between timestamps and actual output */
117 /* set to zero to get immediate, simple blocking output */
118 /* if latency is zero, timestamps will be ignored; */
119 /* if midi input device, this field ignored */
120
121 int sysex_in_progress; /* when sysex status is seen, this flag becomes
122 * true until EOX is seen. When true, new data is appended to the
123 * stream of outgoing bytes. When overflow occurs, sysex data is
124 * dropped (until an EOX or non-real-timei status byte is seen) so
125 * that, if the overflow condition is cleared, we don't start
126 * sending data from the middle of a sysex message. If a sysex
127 * message is filtered, sysex_in_progress is false, causing the
128 * message to be dropped. */
129 PmMessage message; /* buffer for 4 bytes of sysex data */
130 int message_count; /* how many bytes in sysex_message so far */
131 int short_message_count; /* how many bytes are expected in short message */
132 unsigned char running_status; /* running status byte or zero if none */
133 int32_t filters; /* flags that filter incoming message classes */
134 int32_t channel_mask; /* filter incoming messages based on channel */
135 PmTimestamp last_msg_time; /* timestamp of last message */
136 PmTimestamp sync_time; /* time of last synchronization */
137 PmTimestamp now; /* set by PmWrite to current time */
138 int first_message; /* initially true, used to run first synchronization */
139 pm_fns_type dictionary; /* implementation functions */
140 void *api_info; /* system-dependent state */
141 /* the following are used to expedite sysex data */
142 /* on windows, in debug mode, based on some profiling, these optimizations
143 * cut the time to process sysex bytes from about 7.5 to 0.26 usec/byte,
144 * but this does not count time in the driver, so I don't know if it is
145 * important
146 */
147 unsigned char *fill_base; /* addr of ptr to sysex data */
148 uint32_t *fill_offset_ptr; /* offset of next sysex byte */
149 uint32_t fill_length; /* how many sysex bytes to write */
150} PmInternal;
151
152/* what is the length of this short message? */
153int pm_midi_length(PmMessage msg);
154
155/* defined by system specific implementation, e.g. pmwinmm, used by PortMidi */
156void pm_init(void);
157void pm_term(void);
158
159/* defined by portMidi, used by pmwinmm */
160PmError none_write_short(PmInternal *midi, PmEvent *buffer);
161PmError none_write_byte(PmInternal *midi, unsigned char byte,
162 PmTimestamp timestamp);
163PmTimestamp none_synchronize(PmInternal *midi);
164
165PmError pm_fail_fn(PmInternal *midi);
166PmError pm_fail_timestamp_fn(PmInternal *midi, PmTimestamp timestamp);
167PmError pm_success_fn(PmInternal *midi);
168PmError pm_add_interf(char *interf, pm_create_fn create_fn,
169 pm_delete_fn delete_fn);
170PmError pm_add_device(char *interf, const char *name, int is_input,
171 int is_virtual, void *descriptor, pm_fns_type dictionary);
172void pm_undo_add_device(int id);
173uint32_t pm_read_bytes(PmInternal *midi, const unsigned char *data, int len,
174 PmTimestamp timestamp);
175void pm_read_short(PmInternal *midi, PmEvent *event);
176
177#define none_write_flush pm_fail_timestamp_fn
178#define none_sysex pm_fail_timestamp_fn
179#define none_poll pm_fail_fn
180#define success_poll pm_success_fn
181
182#define MIDI_REALTIME_MASK 0xf8
183#define is_real_time(msg) \
184 ((Pm_MessageStatus(msg) & MIDI_REALTIME_MASK) == MIDI_REALTIME_MASK)
185
186#ifdef __cplusplus
187}
188#endif
189
190/** @endcond */
diff --git a/portmidi/pm_common/pmutil.c b/portmidi/pm_common/pmutil.c
new file mode 100755
index 0000000..a70fe2f
--- /dev/null
+++ b/portmidi/pm_common/pmutil.c
@@ -0,0 +1,284 @@
1/* pmutil.c -- some helpful utilities for building midi
2 applications that use PortMidi
3 */
4#include <stdlib.h>
5#include <assert.h>
6#include <string.h>
7#include "portmidi.h"
8#include "pmutil.h"
9#include "pminternal.h"
10
11#ifdef WIN32
12#define bzero(addr, siz) memset(addr, 0, siz)
13#endif
14
15// #define QUEUE_DEBUG 1
16#ifdef QUEUE_DEBUG
17#include "stdio.h"
18#endif
19
20typedef struct {
21 long head;
22 long tail;
23 long len;
24 long overflow;
25 int32_t msg_size; /* number of int32_t in a message including extra word */
26 int32_t peek_overflow;
27 int32_t *buffer;
28 int32_t *peek;
29 int32_t peek_flag;
30} PmQueueRep;
31
32
33PMEXPORT PmQueue *Pm_QueueCreate(long num_msgs, int32_t bytes_per_msg)
34{
35 int32_t int32s_per_msg =
36 (int32_t) (((bytes_per_msg + sizeof(int32_t) - 1) &
37 ~(sizeof(int32_t) - 1)) / sizeof(int32_t));
38 PmQueueRep *queue = (PmQueueRep *) pm_alloc(sizeof(PmQueueRep));
39 if (!queue) /* memory allocation failed */
40 return NULL;
41
42 /* need extra word per message for non-zero encoding */
43 queue->len = num_msgs * (int32s_per_msg + 1);
44 queue->buffer = (int32_t *) pm_alloc(queue->len * sizeof(int32_t));
45 bzero(queue->buffer, queue->len * sizeof(int32_t));
46 if (!queue->buffer) {
47 pm_free(queue);
48 return NULL;
49 } else { /* allocate the "peek" buffer */
50 queue->peek = (int32_t *) pm_alloc(int32s_per_msg * sizeof(int32_t));
51 if (!queue->peek) {
52 /* free everything allocated so far and return */
53 pm_free(queue->buffer);
54 pm_free(queue);
55 return NULL;
56 }
57 }
58 bzero(queue->buffer, queue->len * sizeof(int32_t));
59 queue->head = 0;
60 queue->tail = 0;
61 /* msg_size is in words */
62 queue->msg_size = int32s_per_msg + 1; /* note extra word is counted */
63 queue->overflow = FALSE;
64 queue->peek_overflow = FALSE;
65 queue->peek_flag = FALSE;
66 return queue;
67}
68
69
70PMEXPORT PmError Pm_QueueDestroy(PmQueue *q)
71{
72 PmQueueRep *queue = (PmQueueRep *) q;
73
74 /* arg checking */
75 if (!queue || !queue->buffer || !queue->peek)
76 return pmBadPtr;
77
78 pm_free(queue->peek);
79 pm_free(queue->buffer);
80 pm_free(queue);
81 return pmNoError;
82}
83
84
85PMEXPORT PmError Pm_Dequeue(PmQueue *q, void *msg)
86{
87 long head;
88 PmQueueRep *queue = (PmQueueRep *) q;
89 int i;
90 int32_t *msg_as_int32 = (int32_t *) msg;
91
92 /* arg checking */
93 if (!queue)
94 return pmBadPtr;
95 /* a previous peek operation encountered an overflow, but the overflow
96 * has not yet been reported to client, so do it now. No message is
97 * returned, but on the next call, we will return the peek buffer.
98 */
99 if (queue->peek_overflow) {
100 queue->peek_overflow = FALSE;
101 return pmBufferOverflow;
102 }
103 if (queue->peek_flag) {
104 memcpy(msg, queue->peek, (queue->msg_size - 1) * sizeof(int32_t));
105 queue->peek_flag = FALSE;
106 return pmGotData;
107 }
108
109 head = queue->head;
110 /* if writer overflows, it writes queue->overflow = tail+1 so that
111 * when the reader gets to that position in the buffer, it can
112 * return the overflow condition to the reader. The problem is that
113 * at overflow, things have wrapped around, so tail == head, and the
114 * reader will detect overflow immediately instead of waiting until
115 * it reads everything in the buffer, wrapping around again to the
116 * point where tail == head. So the condition also checks that
117 * queue->buffer[head] is zero -- if so, then the buffer is now
118 * empty, and we're at the point in the msg stream where overflow
119 * occurred. It's time to signal overflow to the reader. If
120 * queue->buffer[head] is non-zero, there's a message there and we
121 * should read all the way around the buffer before signalling overflow.
122 * There is a write-order dependency here, but to fail, the overflow
123 * field would have to be written while an entire buffer full of
124 * writes are still pending. I'm assuming out-of-order writes are
125 * possible, but not that many.
126 */
127 if (queue->overflow == head + 1 && !queue->buffer[head]) {
128 queue->overflow = 0; /* non-overflow condition */
129 return pmBufferOverflow;
130 }
131
132 /* test to see if there is data in the queue -- test from back
133 * to front so if writer is simultaneously writing, we don't
134 * waste time discovering the write is not finished
135 */
136 for (i = queue->msg_size - 1; i >= 0; i--) {
137 if (!queue->buffer[head + i]) {
138 return pmNoData;
139 }
140 }
141 memcpy(msg, (char *) &queue->buffer[head + 1],
142 sizeof(int32_t) * (queue->msg_size - 1));
143 /* fix up zeros */
144 i = queue->buffer[head];
145 while (i < queue->msg_size) {
146 int32_t j;
147 i--; /* msg does not have extra word so shift down */
148 j = msg_as_int32[i];
149 msg_as_int32[i] = 0;
150 i = j;
151 }
152 /* signal that data has been removed by zeroing: */
153 bzero((char *) &queue->buffer[head], sizeof(int32_t) * queue->msg_size);
154
155 /* update head */
156 head += queue->msg_size;
157 if (head == queue->len) head = 0;
158 queue->head = head;
159 return pmGotData; /* success */
160}
161
162
163
164PMEXPORT PmError Pm_SetOverflow(PmQueue *q)
165{
166 PmQueueRep *queue = (PmQueueRep *) q;
167 long tail;
168 /* arg checking */
169 if (!queue)
170 return pmBadPtr;
171 /* no more enqueue until receiver acknowledges overflow */
172 if (queue->overflow) return pmBufferOverflow;
173 tail = queue->tail;
174 queue->overflow = tail + 1;
175 return pmBufferOverflow;
176}
177
178
179PMEXPORT PmError Pm_Enqueue(PmQueue *q, void *msg)
180{
181 PmQueueRep *queue = (PmQueueRep *) q;
182 long tail;
183 int i;
184 int32_t *src = (int32_t *) msg;
185 int32_t *ptr;
186 int32_t *dest;
187 int rslt;
188 if (!queue)
189 return pmBadPtr;
190 /* no more enqueue until receiver acknowledges overflow */
191 if (queue->overflow) return pmBufferOverflow;
192 rslt = Pm_QueueFull(q);
193 /* already checked above: if (rslt == pmBadPtr) return rslt; */
194 tail = queue->tail;
195 if (rslt) {
196 queue->overflow = tail + 1;
197 return pmBufferOverflow;
198 }
199
200 /* queue is has room for message, and overflow flag is cleared */
201 ptr = &queue->buffer[tail];
202 dest = ptr + 1;
203 for (i = 1; i < queue->msg_size; i++) {
204 int32_t j = src[i - 1];
205 if (!j) {
206 *ptr = i;
207 ptr = dest;
208 } else {
209 *dest = j;
210 }
211 dest++;
212 }
213 *ptr = i;
214 tail += queue->msg_size;
215 if (tail == queue->len) tail = 0;
216 queue->tail = tail;
217 return pmNoError;
218}
219
220
221PMEXPORT int Pm_QueueEmpty(PmQueue *q)
222{
223 PmQueueRep *queue = (PmQueueRep *) q;
224 return (!queue) || /* null pointer -> return "empty" */
225 (queue->buffer[queue->head] == 0 && !queue->peek_flag);
226}
227
228
229PMEXPORT int Pm_QueueFull(PmQueue *q)
230{
231 long tail;
232 int i;
233 PmQueueRep *queue = (PmQueueRep *) q;
234 /* arg checking */
235 if (!queue)
236 return pmBadPtr;
237 tail = queue->tail;
238 /* test to see if there is space in the queue */
239 for (i = 0; i < queue->msg_size; i++) {
240 if (queue->buffer[tail + i]) {
241 return TRUE;
242 }
243 }
244 return FALSE;
245}
246
247
248PMEXPORT void *Pm_QueuePeek(PmQueue *q)
249{
250 PmError rslt;
251 int32_t temp;
252 PmQueueRep *queue = (PmQueueRep *) q;
253 /* arg checking */
254 if (!queue)
255 return NULL;
256
257 if (queue->peek_flag) {
258 return queue->peek;
259 }
260 /* this is ugly: if peek_overflow is set, then Pm_Dequeue()
261 * returns immediately with pmBufferOverflow, but here, we
262 * want Pm_Dequeue() to really check for data. If data is
263 * there, we can return it
264 */
265 temp = queue->peek_overflow;
266 queue->peek_overflow = FALSE;
267 rslt = Pm_Dequeue(q, queue->peek);
268 queue->peek_overflow = temp;
269
270 if (rslt == 1) {
271 queue->peek_flag = TRUE;
272 return queue->peek;
273 } else if (rslt == pmBufferOverflow) {
274 /* when overflow is indicated, the queue is empty and the
275 * first message that was dropped by Enqueue (signalling
276 * pmBufferOverflow to its caller) would have been the next
277 * message in the queue. Pm_QueuePeek will return NULL, but
278 * remember that an overflow occurred. (see Pm_Dequeue)
279 */
280 queue->peek_overflow = TRUE;
281 }
282 return NULL;
283}
284
diff --git a/portmidi/pm_common/pmutil.h b/portmidi/pm_common/pmutil.h
new file mode 100755
index 0000000..46c618e
--- /dev/null
+++ b/portmidi/pm_common/pmutil.h
@@ -0,0 +1,184 @@
1/** @file pmutil.h lock-free queue for building MIDI
2 applications with PortMidi.
3
4 PortMidi is not reentrant, and locks can suffer from priority
5 inversion. To support coordination between system callbacks, a
6 high-priority thread created with PortTime, and the main
7 application thread, PortMidi uses a lock-free, non-blocking
8 queue. The queue implementation is not particular to MIDI and is
9 available for other uses.
10 */
11
12#ifndef PORTMIDI_PMUTIL_H
13#define PORTMIDI_PMUTIL_H
14
15#ifdef __cplusplus
16extern "C" {
17#endif /* __cplusplus */
18
19/** @defgroup grp_pmutil Lock-free Queue
20 @{
21*/
22
23/** The queue representation is opaque. Declare a queue as PmQueue * */
24typedef void PmQueue;
25
26/** create a single-reader, single-writer queue.
27
28 @param num_msgs the number of messages the queue can hold
29
30 @param the fixed message size
31
32 @return the allocated and initialized queue, or NULL if memory
33 cannot be allocated. Allocation uses #pm_malloc().
34
35 The queue only accepts fixed sized messages.
36
37 This queue implementation uses the "light pipe" algorithm which
38 operates correctly even with multi-processors and out-of-order
39 memory writes. (see Alexander Dokumentov, "Lock-free Interprocess
40 Communication," Dr. Dobbs Portal, http://www.ddj.com/,
41 articleID=189401457, June 15, 2006. This algorithm requires that
42 messages be translated to a form where no words contain
43 zeros. Each word becomes its own "data valid" tag. Because of this
44 translation, we cannot return a pointer to data still in the queue
45 when the "peek" method is called. Instead, a buffer is
46 preallocated so that data can be copied there. Pm_QueuePeek()
47 dequeues a message into this buffer and returns a pointer to it. A
48 subsequent Pm_Dequeue() will copy from this buffer.
49
50 This implementation does not try to keep reader/writer data in
51 separate cache lines or prevent thrashing on cache lines.
52 However, this algorithm differs by doing inserts/removals in
53 units of messages rather than units of machine words. Some
54 performance improvement might be obtained by not clearing data
55 immediately after a read, but instead by waiting for the end
56 of the cache line, especially if messages are smaller than
57 cache lines. See the Dokumentov article for explanation.
58
59 The algorithm is extended to handle "overflow" reporting. To
60 report an overflow, the sender writes the current tail position to
61 a field. The receiver must acknowlege receipt by zeroing the
62 field. The sender will not send more until the field is zeroed.
63 */
64PMEXPORT PmQueue *Pm_QueueCreate(long num_msgs, int32_t bytes_per_msg);
65
66/** destroy a queue and free its storage.
67
68 @param queue a queue created by #Pm_QueueCreate().
69
70 @return pmNoError or an error code.
71
72 Uses #pm_free().
73
74 */
75PMEXPORT PmError Pm_QueueDestroy(PmQueue *queue);
76
77/** remove one message from the queue, copying it into \p msg.
78
79 @param queue a queue created by #Pm_QueueCreate().
80
81 @param msg address to which the message, if any, is copied.
82
83 @return 1 if successful, and 0 if the queue is empty. Returns
84 #pmBufferOverflow if what would have been the next thing in the
85 queue was dropped due to overflow. (So when overflow occurs, the
86 receiver can receive a queue full of messages before getting the
87 overflow report. This protocol ensures that the reader will be
88 notified when data is lost due to overflow.
89 */
90PMEXPORT PmError Pm_Dequeue(PmQueue *queue, void *msg);
91
92/** insert one message into the queue, copying it from \p msg.
93
94 @param queue a queue created by #Pm_QueueCreate().
95
96 @param msg address of the message to be enqueued.
97
98 @return #pmNoError if successful and #pmBufferOverflow if the
99 queue was already full. If #pmBufferOverflow is returned, the
100 overflow flag is set.
101 */
102PMEXPORT PmError Pm_Enqueue(PmQueue *queue, void *msg);
103
104/** test if the queue is full.
105
106 @param queue a queue created by #Pm_QueueCreate().
107
108 @return non-zero iff the queue is empty, and @pmBadPtr if \p queue
109 is NULL.
110
111 The full condition may change immediately because a parallel
112 dequeue operation could be in progress. The result is
113 pessimistic: if it returns false (zero) to the single writer, then
114 #Pm_Enqueue() is guaranteed to succeed.
115 */
116PMEXPORT int Pm_QueueFull(PmQueue *queue);
117
118/** test if the queue is empty.
119
120 @param queue a queue created by #Pm_QueueCreate().
121
122 @return zero iff the queue is either empty or NULL.
123
124 The empty condition may change immediately because a parallel
125 enqueue operation could be in progress. Furthermore, the
126 result is optimistic: it may say false, when due to
127 out-of-order writes, the full message has not arrived. Therefore,
128 #Pm_Dequeue() could still return 0 after #Pm_QueueEmpty() returns
129 false.
130*/
131PMEXPORT int Pm_QueueEmpty(PmQueue *queue);
132
133/** get a pointer to the item at the head of the queue.
134
135 @param queue a queue created by #Pm_QueueCreate().
136
137 @result a pointer to the head message or NULL if the queue is empty.
138
139 The message is not removed from the queue. #Pm_QueuePeek() will
140 not indicate when an overflow occurs. If you want to get and check
141 #pmBufferOverflow messages, use the return value of
142 #Pm_QueuePeek() *only* as an indication that you should call
143 #Pm_Dequeue(). At the point where a direct call to #Pm_Dequeue()
144 would return #pmBufferOverflow, #Pm_QueuePeek() will return NULL,
145 but internally clear the #pmBufferOverflow flag, enabling
146 #Pm_Enqueue() to resume enqueuing messages. A subsequent call to
147 #Pm_QueuePeek() will return a pointer to the first message *after*
148 the overflow. Using this as an indication to call #Pm_Dequeue(),
149 the first call to #Pm_Dequeue() will return #pmBufferOverflow. The
150 second call will return success, copying the same message pointed
151 to by the previous #Pm_QueuePeek().
152
153 When to use #Pm_QueuePeek(): (1) when you need to look at the message
154 data to decide who should be called to receive it. (2) when you need
155 to know a message is ready but cannot accept the message.
156
157 Note that #Pm_QueuePeek() is not a fast check, so if possible, you
158 might as well just call #Pm_Dequeue() and accept the data if it is there.
159 */
160PMEXPORT void *Pm_QueuePeek(PmQueue *queue);
161
162/** allows the writer (enqueuer) to signal an overflow
163 condition to the reader (dequeuer).
164
165 @param queue a queue created by #Pm_QueueCreate().
166
167 @return #pmNoError if overflow is set, or #pmBadPtr if queue is
168 NULL, or #pmBufferOverflow if buffer is already in an overflow
169 state.
170
171 E.g., when transfering data from the OS to an application, if the
172 OS indicates a buffer overrun, #Pm_SetOverflow() can be used to
173 insure that the reader receives a #pmBufferOverflow result from
174 #Pm_Dequeue().
175 */
176PMEXPORT PmError Pm_SetOverflow(PmQueue *queue);
177
178/** @} */
179
180#ifdef __cplusplus
181}
182#endif /* __cplusplus */
183
184#endif // PORTMIDI_PMUTIL_H
diff --git a/portmidi/pm_common/portmidi.c b/portmidi/pm_common/portmidi.c
new file mode 100755
index 0000000..e78ee73
--- /dev/null
+++ b/portmidi/pm_common/portmidi.c
@@ -0,0 +1,1472 @@
1/* portmidi.c -- cross-platform MIDI I/O library */
2/* see license.txt for license */
3
4#include "stdlib.h"
5#include "string.h"
6#include "portmidi.h"
7#include "porttime.h"
8#include "pmutil.h"
9#include "pminternal.h"
10#include <assert.h>
11
12#define MIDI_CLOCK 0xf8
13#define MIDI_ACTIVE 0xfe
14#define MIDI_STATUS_MASK 0x80
15#define MIDI_SYSEX 0xf0
16#define MIDI_EOX 0xf7
17#define MIDI_START 0xFA
18#define MIDI_STOP 0xFC
19#define MIDI_CONTINUE 0xFB
20#define MIDI_F9 0xF9
21#define MIDI_FD 0xFD
22#define MIDI_RESET 0xFF
23#define MIDI_NOTE_ON 0x90
24#define MIDI_NOTE_OFF 0x80
25#define MIDI_CHANNEL_AT 0xD0
26#define MIDI_POLY_AT 0xA0
27#define MIDI_PROGRAM 0xC0
28#define MIDI_CONTROL 0xB0
29#define MIDI_PITCHBEND 0xE0
30#define MIDI_MTC 0xF1
31#define MIDI_SONGPOS 0xF2
32#define MIDI_SONGSEL 0xF3
33#define MIDI_TUNE 0xF6
34
35#define is_empty(midi) ((midi)->tail == (midi)->head)
36
37/* these are not static so that (possibly) some system-dependent code
38 * could override the portmidi.c default which is to use the first
39 * device added using pm_add_device()
40 */
41PmDeviceID pm_default_input_device_id = -1;
42PmDeviceID pm_default_output_device_id = -1;
43
44/* this is not static so that pm_init can set it directly
45 * (see pmmac.c:pm_init())
46 */
47int pm_initialized = FALSE;
48
49int pm_hosterror; /* boolean */
50
51/* if PM_CHECK_ERRORS is enabled, but the caller wants to
52 * handle an error condition, declare this as extern and
53 * set to FALSE (this override is provided specifically
54 * for the test program virttest.c, where pmNameConflict
55 * is expected in a call to Pm_CreateVirtualInput()):
56 */
57int pm_check_errors = TRUE;
58
59char pm_hosterror_text[PM_HOST_ERROR_MSG_LEN];
60
61#ifdef PM_CHECK_ERRORS
62
63#include <stdio.h>
64
65#define STRING_MAX 80
66
67static void prompt_and_exit(void)
68{
69 char line[STRING_MAX];
70 printf("type ENTER...");
71 char *rslt = fgets(line, STRING_MAX, stdin);
72 /* this will clean up open ports: */
73 exit(-1);
74}
75
76static PmError pm_errmsg(PmError err)
77{
78 if (!pm_check_errors) { /* see pm_check_errors declaration above */
79 ;
80 } else if (err == pmHostError) {
81 /* it seems pointless to allocate memory and copy the string,
82 * so I will do the work of Pm_GetHostErrorText directly
83 */
84 printf("PortMidi found host error...\n %s\n", pm_hosterror_text);
85 pm_hosterror = FALSE;
86 pm_hosterror_text[0] = 0; /* clear the message */
87 prompt_and_exit();
88 } else if (err < 0) {
89 printf("PortMidi call failed...\n %s\n", Pm_GetErrorText(err));
90 prompt_and_exit();
91 }
92 return err;
93}
94#else
95#define pm_errmsg(err) err
96#endif
97
98
99int pm_midi_length(PmMessage msg)
100{
101 int status, high, low;
102 static int high_lengths[] = {
103 1, 1, 1, 1, 1, 1, 1, 1, /* 0x00 through 0x70 */
104 3, 3, 3, 3, 2, 2, 3, 1 /* 0x80 through 0xf0 */
105 };
106 static int low_lengths[] = {
107 1, 2, 3, 2, 1, 1, 1, 1, /* 0xf0 through 0xf8 */
108 1, 1, 1, 1, 1, 1, 1, 1 /* 0xf9 through 0xff */
109 };
110
111 status = msg & 0xFF;
112 high = status >> 4;
113 low = status & 15;
114
115 return (high != 0xF) ? high_lengths[high] : low_lengths[low];
116}
117
118
119/*
120====================================================================
121system implementation of portmidi interface
122====================================================================
123*/
124
125int pm_descriptor_max = 0;
126int pm_descriptor_len = 0;
127descriptor_type pm_descriptors = NULL;
128
129/* interface pm_descriptors are simple: an array of string/fnptr pairs: */
130#define MAX_INTERF 4
131static struct {
132 const char *interf;
133 pm_create_fn create_fn;
134 pm_delete_fn delete_fn;
135} pm_interf_list[MAX_INTERF];
136
137static int pm_interf_list_len = 0;
138
139
140/* pm_add_interf -- describe an interface to library
141 *
142 * This is called at initialization time, once for each
143 * supported interface (e.g., CoreMIDI). The strings
144 * are retained but NOT COPIED, so do not destroy them!
145 *
146 * The purpose is to register functions that create/delete
147 * a virtual input or output device.
148 *
149 * returns pmInsufficientMemor if interface memory is
150 * exceeded, otherwise returns pmNoError.
151 */
152PmError pm_add_interf(char *interf, pm_create_fn create_fn,
153 pm_delete_fn delete_fn)
154{
155 if (pm_interf_list_len >= MAX_INTERF) {
156 return pmInsufficientMemory;
157 }
158 pm_interf_list[pm_interf_list_len].interf = interf;
159 pm_interf_list[pm_interf_list_len].create_fn = create_fn;
160 pm_interf_list[pm_interf_list_len].delete_fn = delete_fn;
161 pm_interf_list_len++;
162 return pmNoError;
163}
164
165
166PmError pm_create_virtual(PmInternal *midi, int is_input, const char *interf,
167 const char *name, void *device_info)
168{
169 int i;
170 if (pm_interf_list_len == 0) {
171 return pmNotImplemented;
172 }
173 if (!interf) {
174 /* default interface is the first one */
175 interf = pm_interf_list[0].interf;
176 }
177 for (i = 0; i < pm_interf_list_len; i++) {
178 if (strcmp(pm_interf_list[i].interf,
179 interf) == 0) {
180 int id = (*pm_interf_list[i].create_fn)(is_input, name,
181 device_info);
182 pm_descriptors[id].pub.is_virtual = TRUE;
183 return id;
184 }
185 }
186 return pmInterfaceNotSupported;
187}
188
189
190/* pm_add_device -- describe interface/device pair to library
191 *
192 * This is called at intialization time, once for each
193 * interface (e.g. DirectSound) and device (e.g. SoundBlaster 1).
194 * This is also called when user creates a virtual device.
195 *
196 * Normally, increasing integer indices are returned. If the device
197 * is virtual, a linear search is performed to ensure that the name
198 * is unique. If the name is already taken, the call will fail and
199 * no device is added.
200 *
201 * interf is assumed to be static memory, so it is NOT COPIED and
202 * NOT FREED.
203 * name is owned by caller, COPIED if needed, and FREED by PortMidi.
204 * Caller is resposible for freeing name when pm_add_device returns.
205 *
206 * returns pmInvalidDeviceId if device memory is exceeded or a virtual
207 * device would take the name of an existing device.
208 * otherwise returns index (portmidi device_id) of the added device
209 */
210PmError pm_add_device(char *interf, const char *name, int is_input,
211 int is_virtual, void *descriptor, pm_fns_type dictionary) {
212 /* printf("pm_add_device: %s %s %d %p %p\n",
213 interf, name, is_input, descriptor, dictionary); */
214 int device_id;
215 PmDeviceInfo *d;
216 /* if virtual, search for duplicate name or unused ID; otherwise,
217 * just add a new device at the next integer available:
218 */
219 for (device_id = (is_virtual ? 0 : pm_descriptor_len);
220 device_id < pm_descriptor_len; device_id++) {
221 d = &pm_descriptors[device_id].pub;
222 d->structVersion = PM_DEVICEINFO_VERS;
223 if (strcmp(d->interf, interf) == 0 && strcmp(d->name, name) == 0) {
224 /* only reuse a name if it is a deleted virtual device with
225 * a matching direction (input or output) */
226 if (pm_descriptors[device_id].deleted && is_input == d->input) {
227 /* here, we know d->is_virtual because only virtual devices
228 * can be deleted, and we know is_virtual because we are
229 * in this loop.
230 */
231 pm_free((void *) d->name); /* reuse this device entry */
232 d->name = NULL;
233 break;
234 /* name conflict exists if the new device appears to others as
235 * the same direction (input or output) as the existing device.
236 * Note that virtual inputs appear to others as outputs and
237 * vice versa.
238 * The direction of the new virtual device to others is "output"
239 * if is_input, i.e., virtual inputs appear to others as outputs.
240 * The existing device appears to others as "output" if
241 * (d->is_virtual == d->input) by the same logic.
242 * The compare will detect if device directions are the same:
243 */
244 } else if (is_input == (d->is_virtual == d->input)) {
245 return pmNameConflict;
246 }
247 }
248 }
249 if (device_id >= pm_descriptor_max) {
250 // expand pm_descriptors
251 descriptor_type new_descriptors = (descriptor_type)
252 pm_alloc(sizeof(descriptor_node) * (pm_descriptor_max + 32));
253 if (!new_descriptors) return pmInsufficientMemory;
254 if (pm_descriptors) {
255 memcpy(new_descriptors, pm_descriptors,
256 sizeof(descriptor_node) * pm_descriptor_max);
257 pm_free(pm_descriptors);
258 }
259 pm_descriptor_max += 32;
260 pm_descriptors = new_descriptors;
261 }
262 if (device_id == pm_descriptor_len) {
263 pm_descriptor_len++; /* extending array of pm_descriptors */
264 }
265 d = &pm_descriptors[device_id].pub;
266 d->interf = interf;
267 d->name = pm_alloc(strlen(name) + 1);
268 if (!d->name) {
269 return pmInsufficientMemory;
270 }
271#if defined(WIN32) && !defined(_WIN32)
272#pragma warning(suppress: 4996) // don't use suggested strncpy_s
273#endif
274 strcpy(d->name, name);
275 d->input = is_input;
276 d->output = !is_input;
277 d->is_virtual = FALSE; /* caller should set to TRUE if this is virtual */
278
279 /* default state: nothing to close (for automatic device closing) */
280 d->opened = FALSE;
281
282 pm_descriptors[device_id].deleted = FALSE;
283
284 /* ID number passed to win32 multimedia API open */
285 pm_descriptors[device_id].descriptor = descriptor;
286
287 /* points to PmInternal, allows automatic device closing */
288 pm_descriptors[device_id].pm_internal = NULL;
289
290 pm_descriptors[device_id].dictionary = dictionary;
291
292 /* set the defaults to the first input and output we see */
293 if (is_input && pm_default_input_device_id == -1) {
294 pm_default_input_device_id = device_id;
295 } else if (!is_input && pm_default_output_device_id == -1) {
296 pm_default_output_device_id = device_id;
297 }
298
299 return device_id;
300}
301
302
303/* Undo a successful call to pm_add_device(). If a new device was
304 * allocated, it must be the last device in pm_descriptors, so it is
305 * easy to delete by decrementing the length of pm_descriptors, but
306 * first free the name (which was copied to the heap). Otherwise,
307 * the device must be a virtual device that was created previously
308 * and is in the interior of the array of pm_descriptors. Leave it,
309 * but mark it as deleted.
310 */
311void pm_undo_add_device(int id)
312{
313 /* Clear some fields (not all are strictly necessary) */
314 pm_descriptors[id].deleted = TRUE;
315 pm_descriptors[id].descriptor = NULL;
316 pm_descriptors[id].pm_internal = NULL;
317
318 if (id == pm_descriptor_len - 1) {
319 pm_free(pm_descriptors[id].pub.name);
320 pm_descriptor_len--;
321 }
322}
323
324
325/* utility to look up device, given a pattern,
326 note: pattern is modified
327 */
328int Pm_FindDevice(char *pattern, int is_input)
329{
330 int id = pmNoDevice;
331 int i;
332 /* first parse pattern into name, interf parts */
333 char *interf_pref = ""; /* initially assume it is not there */
334 char *name_pref = strstr(pattern, ", ");
335
336 if (name_pref) { /* found separator, adjust the pointer */
337 interf_pref = pattern;
338 name_pref[0] = 0;
339 name_pref += 2;
340 } else {
341 name_pref = pattern; /* whole string is the name pattern */
342 }
343 for (i = 0; i < pm_descriptor_len; i++) {
344 const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
345 if (info->input == is_input &&
346 strstr(info->name, name_pref) &&
347 strstr(info->interf, interf_pref)) {
348 id = i;
349 break;
350 }
351 }
352 return id;
353}
354
355
356/*
357====================================================================
358portmidi implementation
359====================================================================
360*/
361
362PMEXPORT int Pm_CountDevices(void)
363{
364 Pm_Initialize();
365 /* no error checking -- Pm_Initialize() does not fail */
366 return pm_descriptor_len;
367}
368
369
370PMEXPORT const PmDeviceInfo* Pm_GetDeviceInfo(PmDeviceID id)
371{
372 Pm_Initialize(); /* no error check needed */
373 if (id >= 0 && id < pm_descriptor_len && !pm_descriptors[id].deleted) {
374 return &pm_descriptors[id].pub;
375 }
376 return NULL;
377}
378
379/* pm_success_fn -- "noop" function pointer */
380PmError pm_success_fn(PmInternal *midi)
381{
382 return pmNoError;
383}
384
385/* none_write -- returns an error if called */
386PmError none_write_short(PmInternal *midi, PmEvent *buffer)
387{
388 return pmBadPtr;
389}
390
391/* pm_fail_timestamp_fn -- placeholder for begin_sysex and flush */
392PmError pm_fail_timestamp_fn(PmInternal *midi, PmTimestamp timestamp)
393{
394 return pmBadPtr;
395}
396
397PmError none_write_byte(PmInternal *midi, unsigned char byte,
398 PmTimestamp timestamp)
399{
400 return pmBadPtr;
401}
402
403/* pm_fail_fn -- generic function, returns error if called */
404PmError pm_fail_fn(PmInternal *midi)
405{
406 return pmBadPtr;
407}
408
409static PmError none_open(PmInternal *midi, void *driverInfo)
410{
411 return pmBadPtr;
412}
413
414static unsigned int none_check_host_error(PmInternal * midi)
415{
416 return FALSE;
417}
418
419PmTimestamp none_synchronize(PmInternal *midi)
420{
421 return 0;
422}
423
424#define none_abort pm_fail_fn
425#define none_close pm_fail_fn
426
427pm_fns_node pm_none_dictionary = {
428 none_write_short,
429 none_sysex,
430 none_sysex,
431 none_write_byte,
432 none_write_short,
433 none_write_flush,
434 none_synchronize,
435 none_open,
436 none_abort,
437 none_close,
438 none_poll,
439 none_check_host_error,
440};
441
442
443PMEXPORT const char *Pm_GetErrorText(PmError errnum)
444{
445 const char *msg;
446
447 switch(errnum)
448 {
449 case pmNoError:
450 msg = "";
451 break;
452 case pmHostError:
453 msg = "PortMidi: Host error";
454 break;
455 case pmInvalidDeviceId:
456 msg = "PortMidi: Invalid device ID";
457 break;
458 case pmInsufficientMemory:
459 msg = "PortMidi: Insufficient memory";
460 break;
461 case pmBufferTooSmall:
462 msg = "PortMidi: Buffer too small";
463 break;
464 case pmBadPtr:
465 msg = "PortMidi: Bad pointer";
466 break;
467 case pmInternalError:
468 msg = "PortMidi: Internal PortMidi Error";
469 break;
470 case pmBufferOverflow:
471 msg = "PortMidi: Buffer overflow";
472 break;
473 case pmBadData:
474 msg = "PortMidi: Invalid MIDI message Data";
475 break;
476 case pmBufferMaxSize:
477 msg = "PortMidi: Buffer cannot be made larger";
478 break;
479 case pmNotImplemented:
480 msg = "PortMidi: Function is not implemented";
481 break;
482 case pmInterfaceNotSupported:
483 msg = "PortMidi: Interface not supported";
484 break;
485 case pmNameConflict:
486 msg = "PortMidi: Cannot create virtual device: name is taken";
487 break;
488 case pmDeviceRemoved:
489 msg = "PortMidi: Output attempted after (USB) device removed";
490 break;
491 default:
492 msg = "PortMidi: Illegal error number";
493 break;
494 }
495 return msg;
496}
497
498
499/* This can be called whenever you get a pmHostError return value
500 * or TRUE from Pm_HasHostError().
501 * The error will always be in the global pm_hosterror_text.
502 */
503PMEXPORT void Pm_GetHostErrorText(char * msg, unsigned int len)
504{
505 assert(msg);
506 assert(len > 0);
507 if (pm_hosterror) {
508#if defined(WIN32) && !defined(_WIN32)
509#pragma warning(suppress: 4996) // don't use suggested strncpy_s
510#endif
511 strncpy(msg, (char *) pm_hosterror_text, len);
512 pm_hosterror = FALSE;
513 pm_hosterror_text[0] = 0; /* clear the message; not necessary, but it
514 might help with debugging */
515 msg[len - 1] = 0; /* make sure string is terminated */
516 } else {
517 msg[0] = 0; /* no string to return */
518 }
519}
520
521
522PMEXPORT int Pm_HasHostError(PortMidiStream * stream)
523{
524 if (pm_hosterror) return TRUE;
525 if (stream) {
526 PmInternal * midi = (PmInternal *) stream;
527 return (*midi->dictionary->check_host_error)(midi);
528 }
529 return FALSE;
530}
531
532
533PMEXPORT PmError Pm_Initialize(void)
534{
535 if (!pm_initialized) {
536 pm_descriptor_len = 0;
537 pm_interf_list_len = 0;
538 pm_hosterror = FALSE;
539 pm_hosterror_text[0] = 0; /* the null string */
540 pm_init();
541 pm_initialized = TRUE;
542 }
543 return pmNoError;
544}
545
546
547PMEXPORT PmError Pm_Terminate(void)
548{
549 if (pm_initialized) {
550 pm_term();
551 /* if there are no devices, pm_descriptors might still be NULL */
552 if (pm_descriptors != NULL) {
553 int i; /* free names copied into pm_descriptors */
554 for (i = 0; i < pm_descriptor_len; i++) {
555 if (pm_descriptors[i].pub.name) {
556 pm_free(pm_descriptors[i].pub.name);
557 }
558 }
559 pm_free(pm_descriptors);
560 pm_descriptors = NULL;
561 }
562 pm_descriptor_len = 0;
563 pm_descriptor_max = 0;
564 pm_interf_list_len = 0;
565 pm_initialized = FALSE;
566 }
567 return pmNoError;
568}
569
570
571/* Pm_Read -- read up to length messages from source into buffer */
572/*
573 * returns number of messages actually read, or error code
574 */
575PMEXPORT int Pm_Read(PortMidiStream *stream, PmEvent *buffer, int32_t length)
576{
577 PmInternal *midi = (PmInternal *) stream;
578 int n = 0;
579 PmError err = pmNoError;
580 pm_hosterror = FALSE;
581 /* arg checking */
582 if(midi == NULL)
583 err = pmBadPtr;
584 else if(!pm_descriptors[midi->device_id].pub.opened)
585 err = pmBadPtr;
586 else if(!pm_descriptors[midi->device_id].pub.input)
587 err = pmBadPtr;
588 /* First poll for data in the buffer...
589 * This either simply checks for data, or attempts first to fill the buffer
590 * with data from the MIDI hardware; this depends on the implementation.
591 * We could call Pm_Poll here, but that would redo a lot of redundant
592 * parameter checking, so I copied some code from Pm_Poll to here: */
593 else err = (*(midi->dictionary->poll))(midi);
594
595 if (err != pmNoError) {
596 if (err == pmHostError) {
597 midi->dictionary->check_host_error(midi);
598 }
599 return pm_errmsg(err);
600 }
601
602 while (n < length) {
603 err = Pm_Dequeue(midi->queue, buffer++);
604 if (err == pmBufferOverflow) {
605 /* ignore the data we have retreived so far */
606 return pm_errmsg(pmBufferOverflow);
607 } else if (err == 0) { /* empty queue */
608 break;
609 }
610 n++;
611 }
612 return n;
613}
614
615PMEXPORT PmError Pm_Poll(PortMidiStream *stream)
616{
617 PmInternal *midi = (PmInternal *) stream;
618 PmError err;
619
620 pm_hosterror = FALSE;
621 /* arg checking */
622 if(midi == NULL)
623 err = pmBadPtr;
624 else if (!pm_descriptors[midi->device_id].pub.opened)
625 err = pmBadPtr;
626 else if (!pm_descriptors[midi->device_id].pub.input)
627 err = pmBadPtr;
628 else
629 err = (*(midi->dictionary->poll))(midi);
630
631 if (err != pmNoError) {
632 return pm_errmsg(err);
633 }
634
635 return (PmError) !Pm_QueueEmpty(midi->queue);
636}
637
638
639/* this is called from Pm_Write and Pm_WriteSysEx to issue a
640 * call to the system-dependent end_sysex function and handle
641 * the error return
642 */
643static PmError pm_end_sysex(PmInternal *midi)
644{
645 PmError err = (*midi->dictionary->end_sysex)(midi, 0);
646 midi->sysex_in_progress = FALSE;
647 return err;
648}
649
650
651/* to facilitate correct error-handling, Pm_Write, Pm_WriteShort, and
652 Pm_WriteSysEx all operate a state machine that "outputs" calls to
653 write_short, begin_sysex, write_byte, end_sysex, and write_realtime */
654
655PMEXPORT PmError Pm_Write(PortMidiStream *stream, PmEvent *buffer,
656 int32_t length)
657{
658 PmInternal *midi = (PmInternal *) stream;
659 PmError err = pmNoError;
660 int i;
661 int bits;
662
663 pm_hosterror = FALSE;
664 /* arg checking */
665 if (midi == NULL) {
666 err = pmBadPtr;
667 } else {
668 descriptor_type desc = &pm_descriptors[midi->device_id];
669 if (!desc || !desc->pub.opened ||
670 !desc->pub.output || !desc->pm_internal) {
671 err = pmBadPtr;
672 } else if (desc->pm_internal->is_removed) {
673 err = pmDeviceRemoved;
674 }
675 }
676 if (err != pmNoError) goto pm_write_error;
677
678 if (midi->latency == 0) {
679 midi->now = 0;
680 } else {
681 midi->now = (*(midi->time_proc))(midi->time_info);
682 if (midi->first_message || midi->sync_time + 100 /*ms*/ < midi->now) {
683 /* time to resync */
684 midi->now = (*midi->dictionary->synchronize)(midi);
685 midi->first_message = FALSE;
686 }
687 }
688 /* error recovery: when a sysex is detected, we call
689 * dictionary->begin_sysex() followed by calls to
690 * dictionary->write_byte() and dictionary->write_realtime()
691 * until an end-of-sysex is detected, when we call
692 * dictionary->end_sysex(). After an error occurs,
693 * Pm_Write() continues to call functions. For example,
694 * it will continue to call write_byte() even after
695 * an error sending a sysex message, and end_sysex() will be
696 * called when an EOX or non-real-time status is found.
697 * When errors are detected, Pm_Write() returns immediately,
698 * so it is possible that this will drop data and leave
699 * sysex messages in a partially transmitted state.
700 */
701 for (i = 0; i < length; i++) {
702 uint32_t msg = buffer[i].message;
703 bits = 0;
704 /* is this a sysex message? */
705 if (Pm_MessageStatus(msg) == MIDI_SYSEX) {
706 if (midi->sysex_in_progress) {
707 /* error: previous sysex was not terminated by EOX */
708 midi->sysex_in_progress = FALSE;
709 err = pmBadData;
710 goto pm_write_error;
711 }
712 midi->sysex_in_progress = TRUE;
713 if ((err = (*midi->dictionary->begin_sysex)(midi,
714 buffer[i].timestamp)) != pmNoError)
715 goto pm_write_error;
716 if ((err = (*midi->dictionary->write_byte)(midi, MIDI_SYSEX,
717 buffer[i].timestamp)) != pmNoError)
718 goto pm_write_error;
719 bits = 8;
720 /* fall through to continue sysex processing */
721 } else if ((msg & MIDI_STATUS_MASK) &&
722 (Pm_MessageStatus(msg) != MIDI_EOX)) {
723 /* a non-sysex message */
724 if (midi->sysex_in_progress) {
725 /* this should be a realtime message */
726 if (is_real_time(msg)) {
727 if ((err = (*midi->dictionary->write_realtime)(midi,
728 &(buffer[i]))) != pmNoError)
729 goto pm_write_error;
730 } else {
731 midi->sysex_in_progress = FALSE;
732 err = pmBadData;
733 /* ignore any error from this, because we already have one */
734 /* pass 0 as timestamp -- it's ignored */
735 (*midi->dictionary->end_sysex)(midi, 0);
736 goto pm_write_error;
737 }
738 } else { /* regular short midi message */
739 if ((err = (*midi->dictionary->write_short)(midi,
740 &(buffer[i]))) != pmNoError)
741 goto pm_write_error;
742 continue;
743 }
744 }
745 if (midi->sysex_in_progress) { /* send sysex bytes until EOX */
746 /* see if we can accelerate data transfer */
747 if (bits == 0 && midi->fill_base && /* 4 bytes to copy */
748 (*midi->fill_offset_ptr) + 4 <= midi->fill_length &&
749 (msg & 0x80808080) == 0) { /* all data */
750 /* copy 4 bytes from msg to fill_base + fill_offset */
751 unsigned char *ptr = midi->fill_base +
752 *(midi->fill_offset_ptr);
753 ptr[0] = msg; ptr[1] = msg >> 8;
754 ptr[2] = msg >> 16; ptr[3] = msg >> 24;
755 (*midi->fill_offset_ptr) += 4;
756 continue;
757 }
758 /* no acceleration, so do byte-by-byte copying */
759 while (bits < 32) {
760 unsigned char midi_byte = (unsigned char) (msg >> bits);
761 if ((err = (*midi->dictionary->write_byte)(midi, midi_byte,
762 buffer[i].timestamp)) != pmNoError)
763 goto pm_write_error;
764 if (midi_byte == MIDI_EOX) {
765 err = pm_end_sysex(midi);
766 if (err != pmNoError) goto error_exit;
767 break; /* from while loop */
768 }
769 bits += 8;
770 }
771 } else {
772 /* not in sysex mode, but message did not start with status */
773 err = pmBadData;
774 goto pm_write_error;
775 }
776 }
777 /* after all messages are processed, send the data */
778 if (!midi->sysex_in_progress)
779 err = (*midi->dictionary->write_flush)(midi, 0);
780pm_write_error:
781 if (err == pmHostError) {
782 midi->dictionary->check_host_error(midi);
783 }
784error_exit:
785 return pm_errmsg(err);
786}
787
788
789PMEXPORT PmError Pm_WriteShort(PortMidiStream *stream, PmTimestamp when,
790 PmMessage msg)
791{
792 PmEvent event;
793
794 event.timestamp = when;
795 event.message = msg;
796 return Pm_Write(stream, &event, 1);
797}
798
799
800PMEXPORT PmError Pm_WriteSysEx(PortMidiStream *stream, PmTimestamp when,
801 unsigned char *msg)
802{
803 /* allocate buffer space for PM_DEFAULT_SYSEX_BUFFER_SIZE bytes */
804 /* each PmEvent holds sizeof(PmMessage) bytes of sysex data */
805 #define BUFLEN ((int) (PM_DEFAULT_SYSEX_BUFFER_SIZE / sizeof(PmMessage)))
806 PmEvent buffer[BUFLEN];
807 int buffer_size = 1; /* first time, send 1. After that, it's BUFLEN */
808 PmInternal *midi = (PmInternal *) stream;
809 PmError err = pmNoError;
810 /* the next byte in the buffer is represented by an index, bufx, and
811 a shift in bits */
812 int shift = 0;
813 int bufx = 0;
814 buffer[0].message = 0;
815 buffer[0].timestamp = when;
816
817 while (1) {
818 /* insert next byte into buffer */
819 buffer[bufx].message |= ((*msg) << shift);
820 shift += 8;
821 if (*msg++ == MIDI_EOX) break;
822 if (shift == 32) {
823 shift = 0;
824 bufx++;
825 if (bufx == buffer_size) {
826 err = Pm_Write(stream, buffer, buffer_size);
827 /* note: Pm_Write has already called errmsg() */
828 if (err) return err;
829 /* prepare to fill another buffer */
830 bufx = 0;
831 buffer_size = BUFLEN;
832 /* optimization: maybe we can just copy bytes */
833 if (midi->fill_base) {
834 while (*(midi->fill_offset_ptr) < midi->fill_length) {
835 midi->fill_base[(*midi->fill_offset_ptr)++] = *msg;
836 if (*msg++ == MIDI_EOX) {
837 err = pm_end_sysex(midi);
838 if (err != pmNoError) return pm_errmsg(err);
839 goto end_of_sysex;
840 }
841 }
842 /* I thought that I could do a pm_Write here and
843 * change this if to a loop, avoiding calls in Pm_Write
844 * to the slower write_byte, but since
845 * sysex_in_progress is true, this will not flush
846 * the buffer, and we'll infinite loop: */
847 /* err = Pm_Write(stream, buffer, 0);
848 if (err) return err; */
849 /* instead, the way this works is that Pm_Write calls
850 * write_byte on 4 bytes. The first, since the buffer
851 * is full, will flush the buffer and allocate a new
852 * one. This primes the buffer so
853 * that we can return to the loop above and fill it
854 * efficiently without a lot of function calls.
855 */
856 buffer_size = 1; /* get another message started */
857 }
858 }
859 buffer[bufx].message = 0;
860 buffer[bufx].timestamp = when;
861 }
862 /* keep inserting bytes until you find MIDI_EOX */
863 }
864end_of_sysex:
865 /* we're finished sending full buffers, but there may
866 * be a partial one left.
867 */
868 if (shift != 0) bufx++; /* add partial message to buffer len */
869 if (bufx) { /* bufx is number of PmEvents to send from buffer */
870 err = Pm_Write(stream, buffer, bufx);
871 if (err) return err;
872 }
873 return pmNoError;
874}
875
876
877
878PmError pm_create_internal(PmInternal **stream, PmDeviceID device_id,
879 int is_input, int latency, PmTimeProcPtr time_proc,
880 void *time_info, int buffer_size)
881{
882 PmInternal *midi;
883 if (device_id < 0 || device_id >= pm_descriptor_len) {
884 return pmInvalidDeviceId;
885 }
886 if (latency < 0) { /* force a legal value */
887 latency = 0;
888 }
889 /* create portMidi internal data */
890 midi = (PmInternal *) pm_alloc(sizeof(PmInternal));
891 *stream = midi;
892 if (!midi) {
893 return pmInsufficientMemory;
894 }
895 midi->device_id = device_id;
896 midi->is_input = is_input;
897 midi->is_removed = FALSE;
898 midi->time_proc = time_proc;
899 /* if latency != 0, we need a time reference for output.
900 we always need a time reference for input.
901 If none is provided, use PortTime library */
902 if (time_proc == NULL && (latency != 0 || is_input)) {
903 if (!Pt_Started())
904 Pt_Start(1, 0, 0);
905 /* time_get does not take a parameter, so coerce */
906 midi->time_proc = (PmTimeProcPtr) Pt_Time;
907 }
908 midi->time_info = time_info;
909 if (is_input) {
910 midi->latency = 0; /* unused by input */
911 if (buffer_size <= 0) buffer_size = 256; /* default buffer size */
912 midi->queue = Pm_QueueCreate(buffer_size, (int32_t) sizeof(PmEvent));
913 if (!midi->queue) {
914 /* free portMidi data */
915 *stream = NULL;
916 pm_free(midi);
917 return pmInsufficientMemory;
918 }
919 } else {
920 /* if latency zero, output immediate (timestamps ignored) */
921 /* if latency < 0, use 0 but don't return an error */
922 if (latency < 0) latency = 0;
923 midi->latency = latency;
924 midi->queue = NULL; /* unused by output; input needs to allocate: */
925 }
926 midi->buffer_len = buffer_size; /* portMidi input storage */
927 midi->sysex_in_progress = FALSE;
928 midi->message = 0;
929 midi->message_count = 0;
930 midi->filters = (is_input ? PM_FILT_ACTIVE : 0);
931 midi->channel_mask = 0xFFFF;
932 midi->sync_time = 0;
933 midi->first_message = TRUE;
934 midi->api_info = NULL;
935 midi->fill_base = NULL;
936 midi->fill_offset_ptr = NULL;
937 midi->fill_length = 0;
938 midi->dictionary = pm_descriptors[device_id].dictionary;
939 pm_descriptors[device_id].pm_internal = midi;
940 return pmNoError;
941}
942
943
944PMEXPORT PmError Pm_OpenInput(PortMidiStream** stream,
945 PmDeviceID inputDevice,
946 void *inputDriverInfo,
947 int32_t bufferSize,
948 PmTimeProcPtr time_proc,
949 void *time_info)
950{
951 PmInternal *midi;
952 PmError err = pmNoError;
953 pm_hosterror = FALSE;
954 *stream = NULL; /* invariant: *stream == midi */
955
956 /* arg checking */
957 if (!pm_descriptors[inputDevice].pub.input)
958 err = pmInvalidDeviceId;
959 else if (pm_descriptors[inputDevice].pub.opened)
960 err = pmInvalidDeviceId;
961 if (err != pmNoError)
962 goto error_return;
963
964 /* common initialization of PmInternal structure (midi): */
965 err = pm_create_internal(&midi, inputDevice, TRUE, 0, time_proc,
966 time_info, bufferSize);
967 *stream = midi;
968 if (err) {
969 goto error_return;
970 }
971
972 /* open system dependent input device */
973 err = (*midi->dictionary->open)(midi, inputDriverInfo);
974 if (err) {
975 *stream = NULL;
976 pm_descriptors[inputDevice].pm_internal = NULL;
977 /* free portMidi data */
978 Pm_QueueDestroy(midi->queue);
979 pm_free(midi);
980 } else {
981 /* portMidi input open successful */
982 pm_descriptors[inputDevice].pub.opened = TRUE;
983 }
984error_return:
985 /* note: if there is a pmHostError, it is the responsibility
986 * of the system-dependent code (*midi->dictionary->open)()
987 * to set pm_hosterror and pm_hosterror_text
988 */
989 return pm_errmsg(err);
990}
991
992
993PMEXPORT PmError Pm_OpenOutput(PortMidiStream** stream,
994 PmDeviceID outputDevice,
995 void *outputDriverInfo,
996 int32_t bufferSize,
997 PmTimeProcPtr time_proc,
998 void *time_info,
999 int32_t latency)
1000{
1001 PmInternal *midi;
1002 PmError err = pmNoError;
1003 pm_hosterror = FALSE;
1004 *stream = NULL;
1005
1006 /* arg checking */
1007 if (outputDevice < 0 || outputDevice >= pm_descriptor_len)
1008 err = pmInvalidDeviceId;
1009 else if (!pm_descriptors[outputDevice].pub.output)
1010 err = pmInvalidDeviceId;
1011 else if (pm_descriptors[outputDevice].pub.opened)
1012 err = pmInvalidDeviceId;
1013 if (err != pmNoError)
1014 goto error_return;
1015
1016 /* common initialization of PmInternal structure (midi): */
1017 err = pm_create_internal(&midi, outputDevice, FALSE, latency, time_proc,
1018 time_info, bufferSize);
1019 *stream = midi;
1020 if (err) {
1021 goto error_return;
1022 }
1023
1024 /* open system dependent output device */
1025 err = (*midi->dictionary->open)(midi, outputDriverInfo);
1026 if (err) {
1027 *stream = NULL;
1028 pm_descriptors[outputDevice].pm_internal = NULL;
1029 /* free portMidi data */
1030 pm_free(midi);
1031 } else {
1032 /* portMidi input open successful */
1033 pm_descriptors[outputDevice].pub.opened = TRUE;
1034 }
1035error_return:
1036 /* note: system-dependent code must set pm_hosterror and
1037 * pm_hosterror_text if a pmHostError occurs
1038 */
1039 return pm_errmsg(err);
1040}
1041
1042
1043static PmError create_virtual_device(const char *name, const char *interf,
1044 void *device_info, int is_input)
1045{
1046 PmError err = pmNoError;
1047 int i;
1048 pm_hosterror = FALSE;
1049
1050 /* arg checking */
1051 if (!name) {
1052 err = pmInvalidDeviceId;
1053 goto error_return;
1054 }
1055
1056 Pm_Initialize(); /* just in case */
1057
1058 /* create the virtual device */
1059 if (pm_interf_list_len == 0) {
1060 return pmNotImplemented;
1061 }
1062 if (!interf) {
1063 /* default interface is the first one */
1064 interf = pm_interf_list[0].interf;
1065 }
1066 /* look up and call the create_fn for interf(ace), e.g. "CoreMIDI" */
1067 for (i = 0; i < pm_interf_list_len; i++) {
1068 if (strcmp(pm_interf_list[i].interf, interf) == 0) {
1069 int id = (*pm_interf_list[i].create_fn)(is_input,
1070 name, device_info);
1071 /* id could be pmNameConflict or an actual descriptor index */
1072 if (id >= 0) {
1073 pm_descriptors[id].pub.is_virtual = TRUE;
1074 }
1075 err = id;
1076 goto error_return;
1077 }
1078 }
1079 err = pmInterfaceNotSupported;
1080
1081error_return:
1082 /* note: if there is a pmHostError, it is the responsibility
1083 * of the system-dependent code (*midi->dictionary->open)()
1084 * to set pm_hosterror and pm_hosterror_text
1085 */
1086 return pm_errmsg(err);
1087}
1088
1089
1090PMEXPORT PmError Pm_CreateVirtualInput(const char *name,
1091 const char *interf,
1092 void *deviceInfo)
1093{
1094 return create_virtual_device(name, interf, deviceInfo, TRUE);
1095}
1096
1097PMEXPORT PmError Pm_CreateVirtualOutput(const char *name, const char *interf,
1098 void *deviceInfo)
1099{
1100 return create_virtual_device(name, interf, deviceInfo, FALSE);
1101}
1102
1103PmError Pm_DeleteVirtualDevice(PmDeviceID id)
1104{
1105 int i;
1106 const char *interf = pm_descriptors[id].pub.interf;
1107 PmError err = pmBadData; /* returned if we cannot find the interface-
1108 * specific delete function */
1109 /* arg checking */
1110 if (id < 0 || id >= pm_descriptor_len ||
1111 pm_descriptors[id].pub.opened || pm_descriptors[id].deleted) {
1112 return pmInvalidDeviceId;
1113 }
1114 /* delete function pointer is in interfaces list */
1115 for (i = 0; i < pm_interf_list_len; i++) {
1116 if (strcmp(pm_interf_list[i].interf, interf) == 0) {
1117 err = (*pm_interf_list[i].delete_fn)(id);
1118 break;
1119 }
1120 }
1121 pm_descriptors[id].deleted = TRUE;
1122 /* (pm_internal should already be NULL because !pub.opened) */
1123 pm_descriptors[id].pm_internal = NULL;
1124 pm_descriptors[id].descriptor = NULL;
1125 return err;
1126}
1127
1128PMEXPORT PmError Pm_SetChannelMask(PortMidiStream *stream, int mask)
1129{
1130 PmInternal *midi = (PmInternal *) stream;
1131 PmError err = pmNoError;
1132
1133 if (midi == NULL)
1134 err = pmBadPtr;
1135 else
1136 midi->channel_mask = mask;
1137
1138 return pm_errmsg(err);
1139}
1140
1141
1142PMEXPORT PmError Pm_SetFilter(PortMidiStream *stream, int32_t filters)
1143{
1144 PmInternal *midi = (PmInternal *) stream;
1145 PmError err = pmNoError;
1146
1147 /* arg checking */
1148 if (midi == NULL)
1149 err = pmBadPtr;
1150 else if (!pm_descriptors[midi->device_id].pub.opened)
1151 err = pmBadPtr;
1152 else
1153 midi->filters = filters;
1154 return pm_errmsg(err);
1155}
1156
1157
1158PMEXPORT PmError Pm_Close(PortMidiStream *stream)
1159{
1160 PmInternal *midi = (PmInternal *) stream;
1161 PmError err = pmNoError;
1162
1163 pm_hosterror = FALSE;
1164 /* arg checking */
1165 if (midi == NULL) /* midi must point to something */
1166 err = pmBadPtr;
1167 /* if it is an open device, the device_id will be valid */
1168 else if (midi->device_id < 0 || midi->device_id >= pm_descriptor_len)
1169 err = pmBadPtr;
1170 /* and the device should be in the opened state */
1171 else if (!pm_descriptors[midi->device_id].pub.opened)
1172 err = pmBadPtr;
1173
1174 if (err != pmNoError)
1175 goto error_return;
1176
1177 /* close the device */
1178 err = (*midi->dictionary->close)(midi);
1179 /* even if an error occurred, continue with cleanup */
1180 pm_descriptors[midi->device_id].pm_internal = NULL;
1181 pm_descriptors[midi->device_id].pub.opened = FALSE;
1182 if (midi->queue) Pm_QueueDestroy(midi->queue);
1183 pm_free(midi);
1184error_return:
1185 /* system dependent code must set pm_hosterror and
1186 * pm_hosterror_text if a pmHostError occurs.
1187 */
1188 return pm_errmsg(err);
1189}
1190
1191PmError Pm_Synchronize(PortMidiStream* stream)
1192{
1193 PmInternal *midi = (PmInternal *) stream;
1194 PmError err = pmNoError;
1195 if (midi == NULL)
1196 err = pmBadPtr;
1197 else if (!pm_descriptors[midi->device_id].pub.output)
1198 err = pmBadPtr;
1199 else if (!pm_descriptors[midi->device_id].pub.opened)
1200 err = pmBadPtr;
1201 else
1202 midi->first_message = TRUE;
1203 return err;
1204}
1205
1206PMEXPORT PmError Pm_Abort(PortMidiStream* stream)
1207{
1208 PmInternal *midi = (PmInternal *) stream;
1209 PmError err;
1210 /* arg checking */
1211 if (midi == NULL)
1212 err = pmBadPtr;
1213 else if (!pm_descriptors[midi->device_id].pub.output)
1214 err = pmBadPtr;
1215 else if (!pm_descriptors[midi->device_id].pub.opened)
1216 err = pmBadPtr;
1217 else
1218 err = (*midi->dictionary->abort)(midi);
1219
1220 if (err == pmHostError) {
1221 midi->dictionary->check_host_error(midi);
1222 }
1223 return pm_errmsg(err);
1224}
1225
1226
1227
1228/* pm_channel_filtered returns non-zero if the channel mask is
1229 blocking the current channel */
1230#define pm_channel_filtered(status, mask) \
1231 ((((status) & 0xF0) != 0xF0) && (!(Pm_Channel((status) & 0x0F) & (mask))))
1232
1233
1234/* The following two functions will checks to see if a MIDI message
1235 matches the filtering criteria. Since the sysex routines only want
1236 to filter realtime messages, we need to have separate routines.
1237 */
1238
1239
1240/* pm_realtime_filtered returns non-zero if the filter will kill the
1241 current message. Note that only realtime messages are checked here.
1242 */
1243#define pm_realtime_filtered(status, filters) \
1244 ((((status) & 0xF0) == 0xF0) && ((1 << ((status) & 0xF)) & (filters)))
1245
1246/*
1247 return ((status == MIDI_ACTIVE) && (filters & PM_FILT_ACTIVE))
1248 || ((status == MIDI_CLOCK) && (filters & PM_FILT_CLOCK))
1249 || ((status == MIDI_START) && (filters & PM_FILT_PLAY))
1250 || ((status == MIDI_STOP) && (filters & PM_FILT_PLAY))
1251 || ((status == MIDI_CONTINUE) && (filters & PM_FILT_PLAY))
1252 || ((status == MIDI_F9) && (filters & PM_FILT_F9))
1253 || ((status == MIDI_FD) && (filters & PM_FILT_FD))
1254 || ((status == MIDI_RESET) && (filters & PM_FILT_RESET))
1255 || ((status == MIDI_MTC) && (filters & PM_FILT_MTC))
1256 || ((status == MIDI_SONGPOS) && (filters & PM_FILT_SONG_POSITION))
1257 || ((status == MIDI_SONGSEL) && (filters & PM_FILT_SONG_SELECT))
1258 || ((status == MIDI_TUNE) && (filters & PM_FILT_TUNE));
1259}*/
1260
1261
1262/* pm_status_filtered returns non-zero if a filter will kill the
1263 current message, based on status. Note that sysex and real time are
1264 not checked. It is up to the subsystem (winmm, core midi, alsa) to
1265 filter sysex, as it is handled more easily and efficiently at that
1266 level. Realtime message are filtered in pm_realtime_filtered.
1267 */
1268#define pm_status_filtered(status, filters) \
1269 ((1 << (16 + ((status) >> 4))) & (filters))
1270
1271
1272/*
1273 return ((status == MIDI_NOTE_ON) && (filters & PM_FILT_NOTE))
1274 || ((status == MIDI_NOTE_OFF) && (filters & PM_FILT_NOTE))
1275 || ((status == MIDI_CHANNEL_AT) &&
1276 (filters & PM_FILT_CHANNEL_AFTERTOUCH))
1277 || ((status == MIDI_POLY_AT) && (filters & PM_FILT_POLY_AFTERTOUCH))
1278 || ((status == MIDI_PROGRAM) && (filters & PM_FILT_PROGRAM))
1279 || ((status == MIDI_CONTROL) && (filters & PM_FILT_CONTROL))
1280 || ((status == MIDI_PITCHBEND) && (filters & PM_FILT_PITCHBEND));
1281
1282}
1283*/
1284
1285static void pm_flush_sysex(PmInternal *midi, PmTimestamp timestamp)
1286{
1287 PmEvent event;
1288
1289 /* there may be nothing in the buffer */
1290 if (midi->message_count == 0) return; /* nothing to flush */
1291
1292 event.message = midi->message;
1293 event.timestamp = timestamp;
1294 /* copied from pm_read_short, avoids filtering */
1295 if (Pm_Enqueue(midi->queue, &event) == pmBufferOverflow) {
1296 midi->sysex_in_progress = FALSE;
1297 }
1298 midi->message_count = 0;
1299 midi->message = 0;
1300}
1301
1302
1303/* pm_read_short and pm_read_bytes
1304 are the interface between system-dependent MIDI input handlers
1305 and the system-independent PortMIDI code.
1306 The input handler MUST obey these rules:
1307 1) all short input messages must be sent to pm_read_short, which
1308 enqueues them to a FIFO for the application.
1309 2) each buffer of sysex bytes should be reported by calling pm_read_bytes
1310 (which sets midi->sysex_in_progress). After the eox byte,
1311 pm_read_bytes will clear sysex_in_progress
1312 */
1313
1314/* pm_read_short is the place where all input messages arrive from
1315 system-dependent code such as pmwinmm.c. Here, the messages
1316 are entered into the PortMidi input buffer.
1317 */
1318void pm_read_short(PmInternal *midi, PmEvent *event)
1319{
1320 int status;
1321 /* arg checking */
1322 assert(midi != NULL);
1323 /* midi filtering is applied here */
1324 status = Pm_MessageStatus(event->message);
1325 if (!pm_status_filtered(status, midi->filters)
1326 && (!is_real_time(status) ||
1327 !pm_realtime_filtered(status, midi->filters))
1328 && !pm_channel_filtered(status, midi->channel_mask)) {
1329 /* if sysex is in progress and we get a status byte, it had
1330 better be a realtime message or the starting SYSEX byte;
1331 otherwise, we exit the sysex_in_progress state
1332 */
1333 if (midi->sysex_in_progress && (status & MIDI_STATUS_MASK)) {
1334 /* two choices: real-time or not. If it's real-time, then
1335 * this should be delivered as a sysex byte because it is
1336 * embedded in a sysex message
1337 */
1338 if (is_real_time(status)) {
1339 midi->message |= (status << (8 * midi->message_count++));
1340 if (midi->message_count == 4) {
1341 pm_flush_sysex(midi, event->timestamp);
1342 }
1343 } else { /* otherwise, it's not real-time. This interrupts
1344 * a sysex message in progress */
1345 midi->sysex_in_progress = FALSE;
1346 }
1347 } else if (Pm_Enqueue(midi->queue, event) == pmBufferOverflow) {
1348 midi->sysex_in_progress = FALSE;
1349 }
1350 }
1351}
1352
1353
1354/* pm_read_bytes -- a sequence of bytes has been read from a device.
1355 * parse the bytes into PmEvents and put them in the queue.
1356 * midi - the midi device
1357 * data - the bytes
1358 * len - the number of bytes
1359 * timestamp - when were the bytes received?
1360 *
1361 * returns how many bytes processed, which is always the len parameter
1362 */
1363unsigned int pm_read_bytes(PmInternal *midi, const unsigned char *data,
1364 int len, PmTimestamp timestamp)
1365{
1366 int i = 0; /* index into data, must not be unsigned (!) */
1367 PmEvent event;
1368 event.timestamp = timestamp;
1369 assert(midi);
1370
1371 /* Since sysex messages may have embedded real-time messages, we
1372 * cannot simply send every consecutive group of 4 bytes as sysex
1373 * data. Instead, we insert each data byte into midi->message and
1374 * keep count using midi->message_count. If we encounter a
1375 * real-time message, it is sent immediately as a 1-byte PmEvent,
1376 * while sysex bytes are sent as PmEvents in groups of 4 bytes
1377 * until the sysex is either terminated by EOX (F7) or a
1378 * non-real-time message is encountered, indicating that the EOX
1379 * was dropped.
1380 */
1381
1382 /* This is a finite state machine so that we can accept any number
1383 * of bytes, even if they contain partial messages.
1384 *
1385 * midi->sysex_in_progress says we are expecting sysex message bytes
1386 * (otherwise, expect a short message or real-time message)
1387 * midi->message accumulates bytes to enqueue for application
1388 * midi->message_count is the number of bytes accumulated
1389 * midi->short_message_count is how many bytes we need in midi->message,
1390 * therefore midi->message_count, before we have a complete message
1391 * midi->running_status is running status or 0 if there is none
1392 *
1393 * Set running status when: A status byte < F0 is received.
1394 * Clear running status when: A status byte from F0 through F7 is
1395 * received.
1396 * Ignore (drop) data bytes when running status is 0.
1397 *
1398 * Our output buffer (the application input buffer) can overflow
1399 * at any time. If that occurs, we have to clear sysex_in_progress
1400 * (otherwise, the buffer could be flushed and we could resume
1401 * inserting sysex bytes into the buffer, resulting in a continuation
1402 * of a sysex message even though a buffer full of bytes was dropped.)
1403 *
1404 * Since we have to parse everything and form <=4-byte PmMessages,
1405 * we send all messages via pm_read_short, which filters messages
1406 * according to midi->filters and clears sysex_in_progress on
1407 * buffer overflow. This also provides a "short cut" for short
1408 * messages that are already parsed, allowing API-specific code
1409 * to bypass this more expensive state machine. What if we are
1410 * getting a sysex message, but it is interrupted by a short
1411 * message (status 80-EF) and a direct call to pm_read_short?
1412 * Without some care, the state machine would still be in
1413 * sysex_in_progress mode, and subsequent data bytes would be
1414 * accumulated as more sysex data, which is wrong since you
1415 * cannot have a short message in the middle of a sysex message.
1416 * To avoid this problem, pm_read_short clears sysex_in_progress
1417 * when a non-real-time short message arrives.
1418 */
1419
1420 while (i < len) {
1421 unsigned char byte = data[i++];
1422 if (is_real_time(byte)) {
1423 event.message = byte;
1424 pm_read_short(midi, &event);
1425 } else if (byte & MIDI_STATUS_MASK && byte != MIDI_EOX) {
1426 midi->message = byte;
1427 midi->message_count = 1;
1428 if (byte == MIDI_SYSEX) {
1429 midi->sysex_in_progress = TRUE;
1430 } else {
1431 midi->sysex_in_progress = FALSE;
1432 midi->short_message_count = pm_midi_length(midi->message);
1433 /* maybe we're done already with a 1-byte message: */
1434 if (midi->short_message_count == 1) {
1435 pm_read_short(midi, &event);
1436 midi->message_count = 0;
1437 }
1438 }
1439 } else if (midi->sysex_in_progress) { /* sysex data byte */
1440 /* accumulate sysex message data or EOX */
1441 midi->message |= (byte << (8 * midi->message_count++));
1442 if (midi->message_count == 4 || byte == MIDI_EOX) {
1443 event.message = midi->message;
1444 /* enqueue if not filtered, and then if there is overflow,
1445 stop sysex_in_progress */
1446 if (!(midi->filters & PM_FILT_SYSEX) &&
1447 Pm_Enqueue(midi->queue, &event) == pmBufferOverflow) {
1448 midi->sysex_in_progress = FALSE;
1449 } else if (byte == MIDI_EOX) { /* continue unless EOX */
1450 midi->sysex_in_progress = FALSE;
1451 }
1452 midi->message_count = 0;
1453 midi->message = 0;
1454 }
1455 } else { /* no sysex in progress, must be short message */
1456 if (midi->message_count == 0) { /* need a running status */
1457 if (midi->running_status) {
1458 midi->message = midi->running_status;
1459 midi->message_count = 1;
1460 } else { /* drop data byte - not sysex and no status byte */
1461 continue;
1462 }
1463 }
1464 midi->message |= (byte << (8 * midi->message_count++));
1465 if (midi->message_count == midi->short_message_count) {
1466 event.message = midi->message;
1467 pm_read_short(midi, &event);
1468 }
1469 }
1470 }
1471 return i;
1472}
diff --git a/portmidi/pm_common/portmidi.h b/portmidi/pm_common/portmidi.h
new file mode 100755
index 0000000..8696a73
--- /dev/null
+++ b/portmidi/pm_common/portmidi.h
@@ -0,0 +1,974 @@
1#ifndef PORTMIDI_PORTMIDI_H
2#define PORTMIDI_PORTMIDI_H
3
4#ifdef __cplusplus
5extern "C" {
6#endif /* __cplusplus */
7
8/*
9 * PortMidi Portable Real-Time MIDI Library
10 * PortMidi API Header File
11 * Latest version available at: http://sourceforge.net/projects/portmedia
12 *
13 * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
14 * Copyright (c) 2001-2006 Roger B. Dannenberg
15 *
16 * Permission is hereby granted, free of charge, to any person obtaining
17 * a copy of this software and associated documentation files
18 * (the "Software"), to deal in the Software without restriction,
19 * including without limitation the rights to use, copy, modify, merge,
20 * publish, distribute, sublicense, and/or sell copies of the Software,
21 * and to permit persons to whom the Software is furnished to do so,
22 * subject to the following conditions:
23 *
24 * The above copyright notice and this permission notice shall be
25 * included in all copies or substantial portions of the Software.
26 *
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
30 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
31 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
32 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 */
35
36/*
37 * The text above constitutes the entire PortMidi license; however,
38 * the PortMusic community also makes the following non-binding requests:
39 *
40 * Any person wishing to distribute modifications to the Software is
41 * requested to send the modifications to the original developer so that
42 * they can be incorporated into the canonical version. It is also
43 * requested that these non-binding requests be included along with the
44 * license above.
45 */
46
47/* CHANGELOG FOR PORTMIDI
48 * (see ../CHANGELOG.txt)
49 *
50 * NOTES ON HOST ERROR REPORTING:
51 *
52 * PortMidi errors (of type PmError) are generic,
53 * system-independent errors. When an error does not map to one of
54 * the more specific PmErrors, the catch-all code pmHostError is
55 * returned. This means that PortMidi has retained a more specific
56 * system-dependent error code. The caller can get more information
57 * by calling Pm_GetHostErrorText() to get a text string describing
58 * the error. Host errors can arise asynchronously from callbacks,
59 * * so there is no specific return code. Asynchronous errors are
60 * checked and reported by Pm_Poll. You can also check by calling
61 * Pm_HasHostError(). If this returns TRUE, Pm_GetHostErrorText()
62 * will return a text description of the error.
63 *
64 * NOTES ON COMPILE-TIME SWITCHES
65 *
66 * DEBUG assumes stdio and a console. Use this if you want
67 * automatic, simple error reporting, e.g. for prototyping. If
68 * you are using MFC or some other graphical interface with no
69 * console, DEBUG probably should be undefined.
70 * PM_CHECK_ERRORS more-or-less takes over error checking for
71 * return values, stopping your program and printing error
72 * messages when an error occurs. This also uses stdio for
73 * console text I/O. You can selectively disable this error
74 * checking by declaring extern int pm_check_errors; and
75 * setting pm_check_errors = FALSE; You can also reenable.
76 */
77/**
78 \defgroup grp_basics Basic Definitions
79 @{
80*/
81
82#include <stdint.h>
83
84#ifdef _WINDLL
85#define PMEXPORT __declspec(dllexport)
86#else
87#define PMEXPORT
88#endif
89
90#ifndef FALSE
91 #define FALSE 0
92#endif
93#ifndef TRUE
94 #define TRUE 1
95#endif
96
97/* default size of buffers for sysex transmission: */
98#define PM_DEFAULT_SYSEX_BUFFER_SIZE 1024
99
100
101typedef enum {
102 pmNoError = 0, /**< Normal return value indicating no error. */
103 pmNoData = 0, /**< @brief No error, also indicates no data available.
104 * Use this constant where a value greater than zero would
105 * indicate data is available.
106 */
107 pmGotData = 1, /**< A "no error" return also indicating data available. */
108 pmHostError = -10000,
109 pmInvalidDeviceId, /**< Out of range or
110 * output device when input is requested or
111 * input device when output is requested or
112 * device is already opened.
113 */
114 pmInsufficientMemory,
115 pmBufferTooSmall,
116 pmBufferOverflow,
117 pmBadPtr, /**< #PortMidiStream parameter is NULL or
118 * stream is not opened or
119 * stream is output when input is required or
120 * stream is input when output is required. */
121 pmBadData, /**< Illegal midi data, e.g., missing EOX. */
122 pmInternalError,
123 pmBufferMaxSize, /**< Buffer is already as large as it can be. */
124 pmNotImplemented, /**< The function is not implemented, nothing was done. */
125 pmInterfaceNotSupported, /**< The requested interface is not supported. */
126 pmNameConflict, /**< Cannot create virtual device because name is taken. */
127 pmDeviceRemoved /**< Output attempted after (USB) device was removed. */
128 /* NOTE: If you add a new error type, you must update Pm_GetErrorText(). */
129} PmError; /**< @brief @enum PmError PortMidi error code; a common return type.
130 * No error is indicated by zero; errors are indicated by < 0.
131 */
132
133/**
134 Pm_Initialize() is the library initialization function - call this before
135 using the library.
136
137 *NOTE:* PortMidi scans for available devices when #Pm_Initialize
138 is called. To observe subsequent changes in the available
139 devices, you must shut down PortMidi by calling #Pm_Terminate and
140 then restart by calling #Pm_Initialize again. *IMPORTANT*: On
141 MacOS, #Pm_Initialize *must* always be called on the same
142 thread. Otherwise, changes in the available MIDI devices will
143 *not* be seen by PortMidi. As an example, if you start PortMidi in
144 a thread for processing MIDI, do not try to rescan devices by
145 calling #Pm_Initialize in a GUI thread. Instead, start PortMidi
146 the first time and every time in the GUI thread. Alternatively,
147 let the GUI request a restart in the MIDI thread. (These
148 restrictions only apply to macOS.) Speaking of threads, on all
149 platforms, you are allowed to call #Pm_Initialize in one thread,
150 yet send MIDI or poll for incoming MIDI in another
151 thread. However, PortMidi is not "thread safe," which means you
152 cannot allow threads to call PortMidi functions concurrently.
153
154 @return pmNoError.
155
156 PortMidi is designed to support multiple interfaces (such as ALSA,
157 CoreMIDI and WinMM). It is possible to return pmNoError because there
158 are no supported interfaces. In that case, zero devices will be
159 available.
160*/
161PMEXPORT PmError Pm_Initialize(void);
162
163/**
164 Pm_Terminate() is the library termination function - call this after
165 using the library.
166*/
167PMEXPORT PmError Pm_Terminate(void);
168
169/** Represents an open MIDI device. */
170typedef void PortMidiStream;
171
172/** A shorter form of #PortMidiStream. */
173#define PmStream PortMidiStream
174
175/** Test whether stream has a pending host error. Normally, the client
176 finds out about errors through returned error codes, but some
177 errors can occur asynchronously where the client does not
178 explicitly call a function, and therefore cannot receive an error
179 code. The client can test for a pending error using
180 Pm_HasHostError(). If true, the error can be accessed by calling
181 Pm_GetHostErrorText(). Pm_Poll() is similar to Pm_HasHostError(),
182 but if there is no error, it will return TRUE (1) if there is a
183 pending input message.
184*/
185PMEXPORT int Pm_HasHostError(PortMidiStream * stream);
186
187
188/** Translate portmidi error number into human readable message.
189 These strings are constants (set at compile time) so client has
190 no need to allocate storage.
191*/
192PMEXPORT const char *Pm_GetErrorText(PmError errnum);
193
194/** Translate portmidi host error into human readable message.
195 These strings are computed at run time, so client has to allocate storage.
196 After this routine executes, the host error is cleared.
197*/
198PMEXPORT void Pm_GetHostErrorText(char * msg, unsigned int len);
199
200/** Any host error msg has at most this many characters, including EOS. */
201#define PM_HOST_ERROR_MSG_LEN 256u
202
203/** Devices are represented as small integers. Device ids range from 0
204 to Pm_CountDevices()-1. Pm_GetDeviceInfo() is used to get information
205 about the device, and Pm_OpenInput() and PmOpenOutput() are used to
206 open the device.
207*/
208typedef int PmDeviceID;
209
210/** This PmDeviceID (constant) value represents no device and may be
211 returned by Pm_GetDefaultInputDeviceID() or
212 Pm_GetDefaultOutputDeviceID() if no default exists.
213*/
214#define pmNoDevice -1
215
216/** MIDI device information is returned in this structure, which is
217 owned by PortMidi and read-only to applications. See Pm_GetDeviceInfo().
218*/
219#define PM_DEVICEINFO_VERS 200
220typedef struct {
221 int structVersion; /**< @brief this internal structure version */
222 const char *interf; /**< @brief underlying MIDI API, e.g.
223 "MMSystem" or "DirectX" */
224 char *name; /**< @brief device name, e.g. "USB MidiSport 1x1" */
225 int input; /**< @brief true iff input is available */
226 int output; /**< @brief true iff output is available */
227 int opened; /**< @brief used by generic PortMidi for error checking */
228 int is_virtual; /**< @brief true iff this is/was a virtual device */
229} PmDeviceInfo;
230
231/** MIDI system-dependent device or driver info is passed in this
232 structure, which is owned by the caller.
233*/
234#define PM_SYSDEPINFO_VERS 210
235
236enum PmSysDepPropertyKey {
237 pmKeyNone = 0, /**< a "noop" key value */
238 /** CoreMIDI Manufacturer name, value is string */
239 pmKeyCoreMidiManufacturer = 1,
240 /** Linux ALSA snd_seq_port_info_set_name, value is a string. Can be
241 passed in PmSysDepInfo to Pm_OpenInput or Pm_OpenOutput when opening
242 a device. The created port will be named accordingly and will be
243 visible for externally made connections (subscriptions). (Linux ALSA
244 ports are always enabled for this, but only get application-specific
245 names if you give it one.) This key/value is ignored when opening
246 virtual ports, which are named when they are created.) */
247 pmKeyAlsaPortName = 2,
248 /** Linux ALSA snd_seq_set_client_name, value is a string.
249 Can be passed in PmSysDepInfo to Pm_OpenInput or Pm_OpenOutput.
250 Pm_CreateVirtualInput or Pm_CreateVirtualOutput. Will override
251 any previously set client name and applies to all ports. */
252 pmKeyAlsaClientName = 3
253 /* if system-dependent code introduces more options, register
254 the key here to avoid conflicts. */
255};
256
257/** System-dependent information can be passed when creating and opening
258 ports using this data structure, which stores alternating keys and
259 values (addresses). See `pm_test/sendvirtual.c`, `pm_test/recvvirtual.c`,
260 and `pm_test/testio.c` for examples.
261 */
262typedef struct {
263 int structVersion; /**< @brief this structure version */
264 int length; /**< @brief number of properties in this structure */
265 struct {
266 enum PmSysDepPropertyKey key;
267 const void *value;
268 } properties[];
269} PmSysDepInfo;
270
271
272/** Get devices count, ids range from 0 to Pm_CountDevices()-1. */
273PMEXPORT int Pm_CountDevices(void);
274
275/**
276 Return the default device ID or pmNoDevice if there are no devices.
277 The result (but not pmNoDevice) can be passed to Pm_OpenMidi().
278
279 The use of these functions is not recommended. There is no natural
280 "default device" on any system, so defaults must be set by users.
281 (Currently, PortMidi just returns the first device it finds as
282 "default", so if there *is* a default, implementors should use
283 pm_add_device to add system default input and output devices
284 first.)
285
286 The recommended solution is pass the burden to applications. It is
287 easy to scan devices with PortMidi and build a device menu, and to
288 save menu selections in application preferences for next
289 time. This is my recommendation for any GUI program. For simple
290 command-line applications and utilities, see pm_test where all the
291 test programs now accept device numbers on the command line and/or
292 prompt for their entry.
293
294 On linux, you can create virtual ports and use an external program
295 to set up inter-application and device connections.
296
297 Some advice for preferences: MIDI devices used to be built-in or
298 plug-in cards, so the numbers rarely changed. Now MIDI devices are
299 often plug-in USB devices, so device numbers change, and you
300 probably need to design to reinitialize PortMidi to rescan
301 devices. MIDI is pretty stateless, so this isn't a big problem,
302 although it means you cannot find a new device while playing or
303 recording MIDI.
304
305 Since device numbering can change whenever a USB device is plugged
306 in, preferences should record *names* of devices rather than
307 device numbers. It is simple enough to use string matching to find
308 a prefered device, so PortMidi does not provide any built-in
309 lookup function.
310*/
311PMEXPORT PmDeviceID Pm_GetDefaultInputDeviceID(void);
312
313/** @brief see PmDeviceID Pm_GetDefaultInputDeviceID() */
314PMEXPORT PmDeviceID Pm_GetDefaultOutputDeviceID(void);
315
316/** Find a device that matches a pattern.
317
318 @param pattern a substring of the device name, or if the pattern
319 contains the two-character separator ", ", then the first part of
320 the pattern represents a device interface substring and the second
321 part after the separator represents a device name substring.
322
323 @param is_input restricts the search to an input when true, or an
324 output when false.
325
326 @return the number of the first device whose device interface
327 contains the interface pattern (if any), whose device name
328 contains the name pattern, and whose direction (input or output)
329 matches the #is_input parameter. If no match is found, #pmNoDevice
330 (-1) is returned.
331*/
332PMEXPORT PmDeviceID Pm_FindDevice(char *pattern, int is_input);
333
334
335/** Represents a millisecond clock with arbitrary start time.
336 This type is used for all MIDI timestamps and clocks.
337*/
338typedef int32_t PmTimestamp;
339typedef PmTimestamp (*PmTimeProcPtr)(void *time_info);
340
341/** TRUE if t1 before t2 */
342#define PmBefore(t1,t2) (((t1)-(t2)) < 0)
343/** @} */
344/**
345 \defgroup grp_device Input/Output Devices Handling
346 @{
347*/
348/** Get a PmDeviceInfo structure describing a MIDI device.
349
350 @param id the device to be queried.
351
352 If \p id is out of range or if the device designates a deleted
353 virtual device, the function returns NULL.
354
355 The returned structure is owned by the PortMidi implementation and
356 must not be manipulated or freed. The pointer is guaranteed to be
357 valid between calls to Pm_Initialize() and Pm_Terminate().
358*/
359PMEXPORT const PmDeviceInfo *Pm_GetDeviceInfo(PmDeviceID id);
360
361/** Open a MIDI device for input.
362
363 @param stream the address of a #PortMidiStream pointer which will
364 receive a pointer to the newly opened stream.
365
366 @param inputDevice the ID of the device to be opened (see #PmDeviceID).
367
368 @param inputSysDepInfo a pointer to an optional system-dependent
369 data structure (a #PmSysDepInfo struct) containing additional
370 information for device setup or handle processing. This parameter
371 is never required for correct operation. If not used, specify
372 NULL. Declared `void *` here for backward compatibility. Note that
373 with Linux ALSA, you can use this parameter to specify a client name
374 and port name.
375
376 @param bufferSize the number of input events to be buffered
377 waiting to be read using Pm_Read(). Messages will be lost if the
378 number of unread messages exceeds this value.
379
380 @param time_proc (address of) a procedure that returns time in
381 milliseconds. It may be NULL, in which case a default millisecond
382 timebase (PortTime) is used. If the application wants to use
383 PortTime, it should start the timer (call Pt_Start) before calling
384 Pm_OpenInput or Pm_OpenOutput. If the application tries to start
385 the timer *after* Pm_OpenInput or Pm_OpenOutput, it may get a
386 ptAlreadyStarted error from Pt_Start, and the application's
387 preferred time resolution and callback function will be ignored.
388 \p time_proc result values are appended to incoming MIDI data,
389 normally by mapping system-provided timestamps to the \p time_proc
390 timestamps to maintain the precision of system-provided
391 timestamps.
392
393 @param time_info is a pointer passed to time_proc.
394
395 @return #pmNoError and places a pointer to a valid
396 #PortMidiStream in the stream argument. If the open operation
397 fails, a nonzero error code is returned (see #PMError) and
398 the value of stream is invalid.
399
400 Any stream that is successfully opened should eventually be closed
401 by calling Pm_Close().
402*/
403PMEXPORT PmError Pm_OpenInput(PortMidiStream** stream,
404 PmDeviceID inputDevice,
405 void *inputSysDepInfo,
406 int32_t bufferSize,
407 PmTimeProcPtr time_proc,
408 void *time_info);
409
410/** Open a MIDI device for output.
411
412 @param stream the address of a #PortMidiStream pointer which will
413 receive a pointer to the newly opened stream.
414
415 @param outputDevice the ID of the device to be opened (see #PmDeviceID).
416
417 @param inputSysDepInfo a pointer to an optional system-specific
418 data structure (a #PmSysDepInfo struct) containing additional
419 information for device setup or handle processing. This parameter
420 is never required for correct operation. If not used, specify
421 NULL. Declared `void *` here for backward compatibility. Note that
422 with Linux ALSA, you can use this parameter to specify a client name
423 and port name.
424
425 @param bufferSize the number of output events to be buffered
426 waiting for output. In some cases -- see below -- PortMidi does
427 not buffer output at all and merely passes data to a lower-level
428 API, in which case \p bufferSize is ignored. Since MIDI speeds now
429 vary from 1 to 50 or more messages per ms (over USB), put some
430 thought into this number. E.g. if latency is 20ms and you want to
431 burst 100 messages in that time (5000 messages per second), you
432 should set \p bufferSize to at least 100. The default on Windows
433 assumes an average rate of 500 messages per second and in this
434 example, output would be slowed waiting for free buffers.
435
436 @param latency the delay in milliseconds applied to timestamps
437 to determine when the output should actually occur. (If latency is
438 < 0, 0 is assumed.) If latency is zero, timestamps are ignored
439 and all output is delivered immediately. If latency is greater
440 than zero, output is delayed until the message timestamp plus the
441 latency. (NOTE: the time is measured relative to the time source
442 indicated by time_proc. Timestamps are absolute, not relative
443 delays or offsets.) In some cases, PortMidi can obtain better
444 timing than your application by passing timestamps along to the
445 device driver or hardware, so the best strategy to minimize jitter
446 is: wait until the real time to send the message, compute the
447 message, attach the *ideal* output time (not the current real
448 time, because some time may have elapsed), and send the
449 message. The \p latency will be added to the timestamp, and
450 provided the elapsed computation time has not exceeded \p latency,
451 the message will be delivered according to the timestamp. If the
452 real time is already past the timestamp, the message will be
453 delivered as soon as possible. Latency may also help you to
454 synchronize MIDI data to audio data by matching \p latency to the
455 audio buffer latency.
456
457 @param time_proc (address of) a pointer to a procedure that
458 returns time in milliseconds. It may be NULL, in which case a
459 default millisecond timebase (PortTime) is used. If the
460 application wants to use PortTime, it should start the timer (call
461 Pt_Start) before calling #Pm_OpenInput or #Pm_OpenOutput. If the
462 application tries to start the timer *after* #Pm_OpenInput or
463 #Pm_OpenOutput, it may get a #ptAlreadyStarted error from #Pt_Start,
464 and the application's preferred time resolution and callback
465 function will be ignored. \p time_proc times are used to schedule
466 outgoing MIDI data (when latency is non-zero), usually by mapping
467 from time_proc timestamps to internal system timestamps to
468 maintain the precision of system-supported timing.
469
470 @param time_info a pointer passed to time_proc.
471
472 @return #pmNoError and places a pointer to a valid #PortMidiStream
473 in the stream argument. If the operation fails, a nonzero error
474 code is returned (see PMError) and the value of \p stream is
475 invalid.
476
477 Note: ALSA appears to have a fixed-size priority queue for timed
478 output messages. Testing indicates the queue can hold a little
479 over 400 3-byte MIDI messages. Thus, you can send 10,000
480 messages/second if the latency is 30ms (30ms * 10000 msgs/sec *
481 0.001 sec/ms = 300 msgs), but not if the latency is 50ms
482 (resulting in about 500 pending messages, which is greater than
483 the 400 message limit). Since timestamps in ALSA are relative,
484 they are of less value than absolute timestamps in macOS and
485 Windows. This is a limitation of ALSA and apparently a design
486 flaw.
487
488 Example 1: If I provide a timestamp of 5000, latency is 1, and
489 time_proc returns 4990, then the desired output time will be when
490 time_proc returns timestamp+latency = 5001. This will be 5001-4990
491 = 11ms from now.
492
493 Example 2: If I want to send at exactly 5010, and latency is 10, I
494 should wait until 5000, compute the messages and provide a
495 timestamp of 5000. As long as computation takes less than 10ms,
496 the message will be delivered at time 5010.
497
498 Example 3 (recommended): It is often convenient to ignore latency.
499 E.g. if a sequence says to output at time 5010, just wait until
500 5010, compute the message and use 5010 for the timestamp. Delivery
501 will then be at 5010+latency, but unless you are synchronizing to
502 something else, the absolute delay by latency will not matter.
503
504 Any stream that is successfully opened should eventually be closed
505 by calling Pm_Close().
506*/
507PMEXPORT PmError Pm_OpenOutput(PortMidiStream** stream,
508 PmDeviceID outputDevice,
509 void *outputSysDepInfo,
510 int32_t bufferSize,
511 PmTimeProcPtr time_proc,
512 void *time_info,
513 int32_t latency);
514
515/** Create a virtual input device.
516
517 @param name gives the virtual device name, which is visible to
518 other applications.
519
520 @param interf is the interface (System API) used to create the
521 device Default interfaces are "MMSystem", "CoreMIDI" and
522 "ALSA". Currently, these are the only ones implemented, but future
523 implementations could support DirectMusic, Jack, sndio, or others.
524
525 @param sysDepInfo contains interface-dependent additional
526 information (a #PmSysDepInfo struct), e.g., hints or options. This
527 parameter is never required for correct operation. If not used,
528 specify NULL. Declared `void *` here for backward compatibility.
529
530 @return a device ID or #pmNameConflict (\p name is invalid or
531 already exists) or #pmInterfaceNotSupported (\p interf is does not
532 match a supported interface).
533
534 The created virtual device appears to other applications as if it
535 is an output device. The device must be opened to obtain a stream
536 and read from it.
537
538 Virtual devices are not supported by Windows (Multimedia API). Calls
539 on Windows do nothing except return #pmNotImplemented.
540*/
541PMEXPORT PmError Pm_CreateVirtualInput(const char *name,
542 const char *interf,
543 void *sysDepInfo);
544
545/** Create a virtual output device.
546
547 @param name gives the virtual device name, which is visible to
548 other applications.
549
550 @param interf is the interface (System API) used to create the
551 device Default interfaces are "MMSystem", "CoreMIDI" and
552 "ALSA". Currently, these are the only ones implemented, but future
553 implementations could support DirectMusic, Jack, sndio, or others.
554
555 @param sysDepInfo contains interface-dependent additional
556 information (a #PmSysDepInfo struct), e.g., hints or options. This
557 parameter is never required for correct operation. If not used,
558 specify NULL. Declared `void *` here for backward compatibility.
559
560 @return a device ID or #pmInvalidDeviceId (\p name is invalid or
561 already exists) or #pmInterfaceNotSupported (\p interf is does not
562 match a supported interface).
563
564 The created virtual device appears to other applications as if it
565 is an input device. The device must be opened to obtain a stream
566 and write to it.
567
568 Virtual devices are not supported by Windows (Multimedia API). Calls
569 on Windows do nothing except return #pmNotImplemented.
570*/
571PMEXPORT PmError Pm_CreateVirtualOutput(const char *name,
572 const char *interf,
573 void *sysDepInfo);
574
575/** Remove a virtual device.
576
577 @param device a device ID (small integer) designating the device.
578
579 The device is removed; other applications can no longer see or open
580 this virtual device, which may be either for input or output. The
581 device must not be open. The device ID may be reused, but existing
582 devices are not renumbered. This means that the device ID could be
583 in the range from 0 to #Pm_CountDevices(), yet the device ID does
584 not designate a device. In that case, passing the ID to
585 #Pm_GetDeviceInfo() will return NULL.
586
587 @return #pmNoError if the device was deleted or #pmInvalidDeviceId
588 if the device is open, already deleted, or \p device is out of
589 range.
590*/
591PMEXPORT PmError Pm_DeleteVirtualDevice(PmDeviceID device);
592 /** @} */
593
594/**
595 @defgroup grp_events_filters Events and Filters Handling
596 @{
597*/
598
599/* Filter bit-mask definitions */
600/** filter active sensing messages (0xFE): */
601#define PM_FILT_ACTIVE (1 << 0x0E)
602/** filter system exclusive messages (0xF0): */
603#define PM_FILT_SYSEX (1 << 0x00)
604/** filter MIDI clock message (0xF8) */
605#define PM_FILT_CLOCK (1 << 0x08)
606/** filter play messages (start 0xFA, stop 0xFC, continue 0xFB) */
607#define PM_FILT_PLAY ((1 << 0x0A) | (1 << 0x0C) | (1 << 0x0B))
608/** filter tick messages (0xF9) */
609#define PM_FILT_TICK (1 << 0x09)
610/** filter undefined FD messages */
611#define PM_FILT_FD (1 << 0x0D)
612/** filter undefined real-time messages */
613#define PM_FILT_UNDEFINED PM_FILT_FD
614/** filter reset messages (0xFF) */
615#define PM_FILT_RESET (1 << 0x0F)
616/** filter all real-time messages */
617#define PM_FILT_REALTIME (PM_FILT_ACTIVE | PM_FILT_SYSEX | PM_FILT_CLOCK | \
618 PM_FILT_PLAY | PM_FILT_UNDEFINED | PM_FILT_RESET | PM_FILT_TICK)
619/** filter note-on and note-off (0x90-0x9F and 0x80-0x8F */
620#define PM_FILT_NOTE ((1 << 0x19) | (1 << 0x18))
621/** filter channel aftertouch (most midi controllers use this) (0xD0-0xDF)*/
622#define PM_FILT_CHANNEL_AFTERTOUCH (1 << 0x1D)
623/** per-note aftertouch (0xA0-0xAF) */
624#define PM_FILT_POLY_AFTERTOUCH (1 << 0x1A)
625/** filter both channel and poly aftertouch */
626#define PM_FILT_AFTERTOUCH (PM_FILT_CHANNEL_AFTERTOUCH | \
627 PM_FILT_POLY_AFTERTOUCH)
628/** Program changes (0xC0-0xCF) */
629#define PM_FILT_PROGRAM (1 << 0x1C)
630/** Control Changes (CC's) (0xB0-0xBF)*/
631#define PM_FILT_CONTROL (1 << 0x1B)
632/** Pitch Bender (0xE0-0xEF*/
633#define PM_FILT_PITCHBEND (1 << 0x1E)
634/** MIDI Time Code (0xF1)*/
635#define PM_FILT_MTC (1 << 0x01)
636/** Song Position (0xF2) */
637#define PM_FILT_SONG_POSITION (1 << 0x02)
638/** Song Select (0xF3)*/
639#define PM_FILT_SONG_SELECT (1 << 0x03)
640/** Tuning request (0xF6) */
641#define PM_FILT_TUNE (1 << 0x06)
642/** All System Common messages (mtc, song position, song select, tune request) */
643#define PM_FILT_SYSTEMCOMMON (PM_FILT_MTC | PM_FILT_SONG_POSITION | \
644 PM_FILT_SONG_SELECT | PM_FILT_TUNE)
645
646
647/* Set filters on an open input stream to drop selected input types.
648
649 @param stream an open MIDI input stream.
650
651 @param filters indicate message types to filter (block).
652
653 @return #pmNoError or an error code.
654
655 By default, only active sensing messages are filtered.
656 To prohibit, say, active sensing and sysex messages, call
657 Pm_SetFilter(stream, PM_FILT_ACTIVE | PM_FILT_SYSEX);
658
659 Filtering is useful when midi routing or midi thru functionality
660 is being provided by the user application.
661 For example, you may want to exclude timing messages (clock, MTC,
662 start/stop/continue), while allowing note-related messages to pass.
663 Or you may be using a sequencer or drum-machine for MIDI clock
664 information but want to exclude any notes it may play.
665 */
666PMEXPORT PmError Pm_SetFilter(PortMidiStream* stream, int32_t filters);
667
668/** Create a mask that filters one channel. */
669#define Pm_Channel(channel) (1<<(channel))
670
671/** Filter incoming messages based on channel.
672
673 @param stream an open MIDI input stream.
674
675 @param mask indicates channels to be received.
676
677 @return #pmNoError or an error code.
678
679 The \p mask is a 16-bit bitfield corresponding to appropriate channels.
680 The #Pm_Channel macro can assist in calling this function.
681 I.e. to receive only input on channel 1, call with
682 Pm_SetChannelMask(Pm_Channel(1));
683 Multiple channels should be OR'd together, like
684 Pm_SetChannelMask(Pm_Channel(10) | Pm_Channel(11))
685
686 Note that channels are numbered 0 to 15 (not 1 to 16). Most
687 synthesizer and interfaces number channels starting at 1, but
688 PortMidi numbers channels starting at 0.
689
690 All channels are allowed by default
691*/
692PMEXPORT PmError Pm_SetChannelMask(PortMidiStream *stream, int mask);
693
694/** Terminate outgoing messages immediately.
695
696 @param stream an open MIDI output stream.
697
698 @result #pmNoError or an error code.
699
700 The caller should immediately close the output port; this call may
701 result in transmission of a partial MIDI message. There is no
702 abort for Midi input because the user can simply ignore messages
703 in the buffer and close an input device at any time. If the
704 specified behavior cannot be achieved through the system-level
705 interface (ALSA, CoreMIDI, etc.), the behavior may be that of
706 Pm_Close().
707 */
708PMEXPORT PmError Pm_Abort(PortMidiStream* stream);
709
710/** Close a midi stream, flush any pending buffers if possible.
711
712 @param stream an open MIDI input or output stream.
713
714 @result #pmNoError or an error code.
715
716 If the system-level interface (ALSA, CoreMIDI, etc.) does not
717 support flushing remaining messages, the behavior may be one of
718 the following (most preferred first): block until all pending
719 timestamped messages are delivered; deliver messages to a server
720 or kernel process for later delivery but return immediately; drop
721 messages (as in Pm_Abort()). Therefore, to be safe, applications
722 should wait until the output queue is empty before calling
723 Pm_Close(). E.g. calling Pt_Sleep(100 + latency); will give a
724 100ms "cushion" beyond latency (if any) before closing.
725*/
726PMEXPORT PmError Pm_Close(PortMidiStream* stream);
727
728/** (re)synchronize to the time_proc passed when the stream was opened.
729
730 @param stream an open MIDI input or output stream.
731
732 @result #pmNoError or an error code.
733
734 Typically, this is used when the stream must be opened before the
735 time_proc reference is actually advancing. In this case, message
736 timing may be erratic, but since timestamps of zero mean "send
737 immediately," initialization messages with zero timestamps can be
738 written without a functioning time reference and without
739 problems. Before the first MIDI message with a non-zero timestamp
740 is written to the stream, the time reference must begin to advance
741 (for example, if the time_proc computes time based on audio
742 samples, time might begin to advance when an audio stream becomes
743 active). After time_proc return values become valid, and BEFORE
744 writing the first non-zero timestamped MIDI message, call
745 Pm_Synchronize() so that PortMidi can observe the difference
746 between the current time_proc value and its MIDI stream time.
747
748 In the more normal case where time_proc values advance
749 continuously, there is no need to call #Pm_Synchronize. PortMidi
750 will always synchronize at the first output message and
751 periodically thereafter.
752*/
753PMEXPORT PmError Pm_Synchronize(PortMidiStream* stream);
754
755
756/** Encode a short Midi message into a 32-bit word. If data1
757 and/or data2 are not present, use zero.
758*/
759#define Pm_Message(status, data1, data2) \
760 ((((data2) << 16) & 0xFF0000) | \
761 (((data1) << 8) & 0xFF00) | \
762 ((status) & 0xFF))
763/** Extract the status field from a 32-bit midi message. */
764#define Pm_MessageStatus(msg) ((msg) & 0xFF)
765/** Extract the 1st data field (e.g., pitch) from a 32-bit midi message. */
766#define Pm_MessageData1(msg) (((msg) >> 8) & 0xFF)
767/** Extract the 2nd data field (e.g., velocity) from a 32-bit midi message. */
768#define Pm_MessageData2(msg) (((msg) >> 16) & 0xFF)
769
770typedef uint32_t PmMessage; /**< @brief see #PmEvent */
771/**
772 All MIDI data comes in the form of PmEvent structures. A sysex
773 message is encoded as a sequence of PmEvent structures, with each
774 structure carrying 4 bytes of the message, i.e. only the first
775 PmEvent carries the status byte.
776
777 All other MIDI messages take 1 to 3 bytes and are encoded in a whole
778 PmMessage with status in the low-order byte and remaining bytes
779 unused, i.e., a 3-byte note-on message will occupy 3 low-order bytes
780 of PmMessage, leaving the high-order byte unused.
781
782 Note that MIDI allows nested messages: the so-called "real-time" MIDI
783 messages can be inserted into the MIDI byte stream at any location,
784 including within a sysex message. MIDI real-time messages are one-byte
785 messages used mainly for timing (see the MIDI spec). PortMidi retains
786 the order of non-real-time MIDI messages on both input and output, but
787 it does not specify exactly how real-time messages are processed. This
788 is particulary problematic for MIDI input, because the input parser
789 must either prepare to buffer an unlimited number of sysex message
790 bytes or to buffer an unlimited number of real-time messages that
791 arrive embedded in a long sysex message. To simplify things, the input
792 parser is allowed to pass real-time MIDI messages embedded within a
793 sysex message, and it is up to the client to detect, process, and
794 remove these messages as they arrive.
795
796 When receiving sysex messages, the sysex message is terminated
797 by either an EOX status byte (anywhere in the 4 byte messages) or
798 by a non-real-time status byte in the low order byte of the message.
799 If you get a non-real-time status byte but there was no EOX byte, it
800 means the sysex message was somehow truncated. This is not
801 considered an error; e.g., a missing EOX can result from the user
802 disconnecting a MIDI cable during sysex transmission.
803
804 A real-time message can occur within a sysex message. A real-time
805 message will always occupy a full PmEvent with the status byte in
806 the low-order byte of the PmEvent message field. (This implies that
807 the byte-order of sysex bytes and real-time message bytes may not
808 be preserved -- for example, if a real-time message arrives after
809 3 bytes of a sysex message, the real-time message will be delivered
810 first. The first word of the sysex message will be delivered only
811 after the 4th byte arrives, filling the 4-byte PmEvent message field.
812
813 The timestamp field is observed when the output port is opened with
814 a non-zero latency. A timestamp of zero means "use the current time",
815 which in turn means to deliver the message with a delay of
816 latency (the latency parameter used when opening the output port.)
817 Do not expect PortMidi to sort data according to timestamps --
818 messages should be sent in the correct order, and timestamps MUST
819 be non-decreasing. See also "Example" for Pm_OpenOutput() above.
820
821 A sysex message will generally fill many #PmEvent structures. On
822 output to a #PortMidiStream with non-zero latency, the first timestamp
823 on sysex message data will determine the time to begin sending the
824 message. PortMidi implementations may ignore timestamps for the
825 remainder of the sysex message.
826
827 On input, the timestamp ideally denotes the arrival time of the
828 status byte of the message. The first timestamp on sysex message
829 data will be valid. Subsequent timestamps may denote
830 when message bytes were actually received, or they may be simply
831 copies of the first timestamp.
832
833 Timestamps for nested messages: If a real-time message arrives in
834 the middle of some other message, it is enqueued immediately with
835 the timestamp corresponding to its arrival time. The interrupted
836 non-real-time message or 4-byte packet of sysex data will be enqueued
837 later. The timestamp of interrupted data will be equal to that of
838 the interrupting real-time message to insure that timestamps are
839 non-decreasing.
840 */
841typedef struct {
842 PmMessage message;
843 PmTimestamp timestamp;
844} PmEvent;
845
846/** @} */
847
848/** \defgroup grp_io Reading and Writing Midi Messages
849 @{
850*/
851/** Retrieve midi data into a buffer.
852
853 @param stream the open input stream.
854
855 @return the number of events read, or, if the result is negative,
856 a #PmError value will be returned.
857
858 The Buffer Overflow Problem
859
860 The problem: if an input overflow occurs, data will be lost,
861 ultimately because there is no flow control all the way back to
862 the data source. When data is lost, the receiver should be
863 notified and some sort of graceful recovery should take place,
864 e.g. you shouldn't resume receiving in the middle of a long sysex
865 message.
866
867 With a lock-free fifo, which is pretty much what we're stuck with
868 to enable portability to the Mac, it's tricky for the producer and
869 consumer to synchronously reset the buffer and resume normal
870 operation.
871
872 Solution: the entire buffer managed by PortMidi will be flushed
873 when an overflow occurs. The consumer (Pm_Read()) gets an error
874 message (#pmBufferOverflow) and ordinary processing resumes as
875 soon as a new message arrives. The remainder of a partial sysex
876 message is not considered to be a "new message" and will be
877 flushed as well.
878*/
879PMEXPORT int Pm_Read(PortMidiStream *stream, PmEvent *buffer, int32_t length);
880
881/** Test whether input is available.
882
883 @param stream an open input stream.
884
885 @return TRUE, FALSE, or an error value.
886
887 If there was an asynchronous error, pmHostError is returned and you must
888 call again to determine if input is (also) available.
889
890 You should probably *not* use this function. Call Pm_Read()
891 instead. If it returns 0, then there is no data available. It is
892 possible for Pm_Poll() to return TRUE before the complete message
893 is available, so Pm_Read() could return 0 even after Pm_Poll()
894 returns TRUE. Only call Pm_Poll() if you want to know that data is
895 probably available even though you are not ready to receive data.
896*/
897PMEXPORT PmError Pm_Poll(PortMidiStream *stream);
898
899/** Write MIDI data from a buffer.
900
901 @param stream an open output stream.
902
903 @param buffer (address of) an array of MIDI event data.
904
905 @param length the length of the \p buffer.
906
907 @return TRUE, FALSE, or an error value.
908
909 \b buffer may contain:
910 - short messages
911 - sysex messages that are converted into a sequence of PmEvent
912 structures, e.g. sending data from a file or forwarding them
913 from midi input, with 4 SysEx bytes per PmEvent message,
914 low-order byte first, until the last message, which may
915 contain from 1 to 4 bytes ending in MIDI EOX (0xF7).
916 - PortMidi allows 1-byte real-time messages to be embedded
917 within SysEx messages, but only on 4-byte boundaries so
918 that SysEx data always uses a full 4 bytes (except possibly
919 at the end). Each real-time message always occupies a full
920 PmEvent (3 of the 4 bytes in the PmEvent's message are
921 ignored) even when embedded in a SysEx message.
922
923 Use Pm_WriteSysEx() to write a sysex message stored as a contiguous
924 array of bytes.
925
926 Sysex data may contain embedded real-time messages.
927
928 \p buffer is managed by the caller. The buffer may be destroyed
929 as soon as this call returns.
930*/
931PMEXPORT PmError Pm_Write(PortMidiStream *stream, PmEvent *buffer,
932 int32_t length);
933
934/** Write a timestamped non-system-exclusive midi message.
935
936 @param stream an open output stream.
937
938 @param when timestamp for the event.
939
940 @param msg the data for the event.
941
942 @result #pmNoError or an error code.
943
944 Messages are delivered in order, and timestamps must be
945 non-decreasing. (But timestamps are ignored if the stream was
946 opened with latency = 0, and otherwise, non-decreasing timestamps
947 are "corrected" to the lowest valid value.)
948*/
949PMEXPORT PmError Pm_WriteShort(PortMidiStream *stream, PmTimestamp when,
950 PmMessage msg);
951
952/** Write a timestamped system-exclusive midi message.
953
954 @param stream an open output stream.
955
956 @param when timestamp for the event.
957
958 @param msg the sysex message, terminated with an EOX status byte.
959
960 @result #pmNoError or an error code.
961
962 \p msg is managed by the caller and may be destroyed when this
963 call returns.
964*/
965PMEXPORT PmError Pm_WriteSysEx(PortMidiStream *stream, PmTimestamp when,
966 unsigned char *msg);
967
968/** @} */
969
970#ifdef __cplusplus
971}
972#endif /* __cplusplus */
973
974#endif /* PORTMIDI_PORTMIDI_H */