1/*
2 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26#ifndef PLATFORM_MIDI_INCLUDED
27#define PLATFORM_MIDI_INCLUDED
28
29
30#include "SoundDefs.h"
31#include "Configure.h" // put flags for debug msgs etc. here
32#include "Utilities.h"
33
34
35/* do we need the queue ? */
36#if (USE_PLATFORM_MIDI_IN == TRUE) || (USE_PLATFORM_MIDI_OUT == TRUE)
37 #if X_PLATFORM == X_WINDOWS || X_PLATFORM == X_MACOSX
38 #define USE_MIDI_QUEUE TRUE
39 #endif
40#endif
41
42/* *********************** MIDI TYPES (for all platforms) ******************************* */
43
44/* return value for functions to denote successful completion */
45#define MIDI_SUCCESS 0
46/* code if function is not supported */
47#define MIDI_NOT_SUPPORTED -11111
48/* return code for invalid handle */
49#define MIDI_INVALID_DEVICEID -11112
50/* return code for invalid handle */
51#define MIDI_INVALID_HANDLE -11113
52/* return code for invalid argument */
53#define MIDI_INVALID_ARGUMENT -11114
54/* return code for out of memory */
55#define MIDI_OUT_OF_MEMORY -11115
56
57// MIDI message types
58typedef enum {
59 SHORT_MESSAGE = 0,
60 LONG_MESSAGE = 1
61} MidiMessageType;
62
63// MIDI message object
64typedef struct tag_MidiMessage {
65 INT64 timestamp; // in microseconds
66 INT32 locked; // TRUE when event is currently being read
67 MidiMessageType type;
68 union {
69 struct {
70 // platform-endianness packed message:
71 // status | data1<<8 | data2<<16
72 UINT32 packedMsg;
73 } s; // short message
74 struct {
75 UINT32 size;
76 // this buffer is read only. It must not be freed.
77 UBYTE* data;
78 INT32 index; // sysex buffer number
79 } l; // long message
80 } data;
81} MidiMessage;
82
83/* error handling. Implemented in PlatformMidi.c */
84char* MIDI_IN_InternalGetErrorString(INT32 err);
85char* MIDI_OUT_InternalGetErrorString(INT32 err);
86
87
88#if USE_MIDI_QUEUE == TRUE
89/*
90 * Native MIDI message circular buffer
91 */
92typedef struct tag_MidiQueue {
93 void* lock;
94 INT32 size;
95 INT32 capacity;
96 INT32 readIndex;
97 INT32 writeIndex;
98 MidiMessage queue[1];
99} MidiMessageQueue;
100#endif
101
102// device handle, to be created and filled in MIDI_IN_OpenDevice() and MIDI_OUT_OpenDevice()
103typedef struct tag_MidiDeviceHandle {
104 void* deviceHandle; // handle to the device
105 void* longBuffers; // contains platform-specific data for long buffers, e.g. list of MIDIHDR
106 void* platformData; // contains platform specific data, e.g. an Event object
107 INT32 isWaiting; // if TRUE, then waiting for new events
108 INT64 startTime; // start time
109#if USE_MIDI_QUEUE == TRUE
110 MidiMessageQueue* queue; // may be NULL if no queue is used
111#endif
112} MidiDeviceHandle;
113
114
115#if USE_MIDI_QUEUE == TRUE
116
117/*
118 * Native Locking support
119 */
120void* MIDI_CreateLock();
121void MIDI_DestroyLock(void* lock);
122
123/* Blocks until this lock can be gotten.
124 * Nop if lock is NULL */
125void MIDI_Lock(void* lock);
126
127/* Releases this lock */
128void MIDI_Unlock(void* lock);
129
130MidiMessageQueue* MIDI_CreateQueue(int capacity);
131void MIDI_DestroyQueue(MidiMessageQueue* queue);
132// if overwrite is true, oldest messages will be overwritten when the queue is full
133// returns true, if message has been added
134int MIDI_QueueAddShort(MidiMessageQueue* queue, UINT32 packedMsg, INT64 timestamp, int overwrite);
135int MIDI_QueueAddLong(MidiMessageQueue* queue, UBYTE* data, UINT32 size,
136 INT32 sysexIndex, INT64 timestamp, int overwrite);
137
138// returns NULL if no messages in queue.
139MidiMessage* MIDI_QueueRead(MidiMessageQueue* queue);
140// message will be removed from queue.
141void MIDI_QueueRemove(MidiMessageQueue* queue, INT32 onlyLocked);
142void MIDI_QueueClear(MidiMessageQueue* queue);
143
144#endif /* USE_MIDI_QUEUE */
145
146
147/*
148 * Platform MIDI IN support.
149 * deviceId: device-by-number
150 * deviceHandle: native device handle
151 */
152
153#if USE_PLATFORM_MIDI_IN == TRUE
154
155// number of messages to be buffered
156#define MIDI_IN_MESSAGE_QUEUE_SIZE 64
157// number of sysex to be buffered
158#define MIDI_IN_LONG_QUEUE_SIZE 20
159// maximum number of bytes in one sys ex message
160#define MIDI_IN_LONG_MESSAGE_SIZE 1024
161
162
163/*
164 * Return an error message for the error code
165 */
166char* MIDI_IN_GetErrorStr(INT32 err);
167
168
169/*
170 * Get the number of MIDI IN devices on the system.
171 */
172INT32 MIDI_IN_GetNumDevices();
173
174/*
175 * Get the name of the device with this id
176 * Returns MIDI_SUCCESS or an error code
177 */
178INT32 MIDI_IN_GetDeviceName(INT32 deviceID, char *name, UINT32 nameLength);
179
180/*
181 * Get the vendor of the device with this id
182 * Returns MIDI_SUCCESS or an error code
183 */
184INT32 MIDI_IN_GetDeviceVendor(INT32 deviceID, char *name, UINT32 nameLength);
185
186/*
187 * Get the description of the device with this id
188 * Returns MIDI_SUCCESS or an error code
189 */
190INT32 MIDI_IN_GetDeviceDescription(INT32 deviceID, char *name, UINT32 nameLength);
191
192/*
193 * Get the version of the device with this id
194 * Returns MIDI_SUCCESS or an error code
195 */
196INT32 MIDI_IN_GetDeviceVersion(INT32 deviceID, char *name, UINT32 nameLength);
197
198/*
199 * Open the device with this id.
200 * Returns a device handle in handle*.
201 * Returns MIDI_SUCCESS or an error code
202 */
203INT32 MIDI_IN_OpenDevice(INT32 deviceID, MidiDeviceHandle** handle);
204
205/*
206 * Close the device handle.
207 * Returns MIDI_SUCCESS or an error code
208 */
209INT32 MIDI_IN_CloseDevice(MidiDeviceHandle* handle);
210
211/*
212 * Start the device with this handle.
213 * Returns MIDI_SUCCESS or an error code
214 */
215INT32 MIDI_IN_StartDevice(MidiDeviceHandle* handle);
216
217/*
218 * Stop the device with this handle.
219 * Returns MIDI_SUCCESS or an error code
220 */
221INT32 MIDI_IN_StopDevice(MidiDeviceHandle* handle);
222
223/*
224 * Return the current time stamp in microseconds.
225 * If not supported, or problem occurred, returns -1
226 */
227INT64 MIDI_IN_GetTimeStamp(MidiDeviceHandle* handle);
228
229/*
230 * Get the next message from the queue.
231 * This call blocks until the device is stopped
232 * or a message is received.
233 * The returned message is READ ONLY.
234 * The message will be returned into the message
235 * queue by calling MIDI_IN_ReleaseMessage.
236 */
237MidiMessage* MIDI_IN_GetMessage(MidiDeviceHandle* handle);
238
239/*
240 * Put a message, which was taken
241 * out of the queue, back into the queue.
242 */
243void MIDI_IN_ReleaseMessage(MidiDeviceHandle* handle, MidiMessage* msg);
244
245#endif // USE_PLATFORM_MIDI_IN
246
247
248/*
249 * Platform MIDI OUT support.
250 * deviceId: device-by-number
251 * deviceHandle: native device handle
252 */
253
254#if USE_PLATFORM_MIDI_OUT == TRUE
255
256// number of messages to be buffered
257#define MIDI_OUT_MESSAGE_QUEUE_SIZE 32
258// number of sysex to be buffered
259#define MIDI_OUT_LONG_QUEUE_SIZE 16
260// maximum number of bytes in one sys ex message
261#define MIDI_OUT_LONG_MESSAGE_SIZE 1024
262
263/*
264 * Return an error message for the error code
265 */
266char* MIDI_OUT_GetErrorStr(INT32 err);
267
268
269/*
270 * Get the number of MIDI OUT devices on the system.
271 */
272INT32 MIDI_OUT_GetNumDevices();
273
274/*
275 * Get the name of the device with this id
276 * Returns MIDI_SUCCESS or an error code
277 */
278INT32 MIDI_OUT_GetDeviceName(INT32 deviceID, char *name, UINT32 nameLength);
279
280/*
281 * Get the vendor of the device with this id
282 * Returns MIDI_SUCCESS or an error code
283 */
284INT32 MIDI_OUT_GetDeviceVendor(INT32 deviceID, char *name, UINT32 nameLength);
285
286/*
287 * Get the description of the device with this id
288 * Returns MIDI_SUCCESS or an error code
289 */
290INT32 MIDI_OUT_GetDeviceDescription(INT32 deviceID, char *name, UINT32 nameLength);
291
292/*
293 * Get the version of the device with this id
294 * Returns MIDI_SUCCESS or an error code
295 */
296INT32 MIDI_OUT_GetDeviceVersion(INT32 deviceID, char *name, UINT32 nameLength);
297
298/*
299 * Open the device with this id.
300 * Returns a device handle in handle*.
301 * Returns MIDI_SUCCESS or an error code
302 */
303INT32 MIDI_OUT_OpenDevice(INT32 deviceID, MidiDeviceHandle** handle);
304
305/*
306 * Close the device handle.
307 * Returns MIDI_SUCCESS or an error code
308 */
309INT32 MIDI_OUT_CloseDevice(MidiDeviceHandle* handle);
310
311/*
312 * Return the current time stamp in microseconds (the time since the device
313 * was opened).
314 * If not supported, or problem occurred, returns -1
315 */
316INT64 MIDI_OUT_GetTimeStamp(MidiDeviceHandle* handle);
317
318/*
319 * Send a short message to the hardware.
320 * packedMsg: (status | data1<<8 | data2<<16) in platform-endianness
321 * Timestamp is in microseconds.
322 * Returns MIDI_SUCCESS or an error code
323 */
324INT32 MIDI_OUT_SendShortMessage(MidiDeviceHandle* handle, UINT32 packedMsg, UINT32 timestamp);
325
326/*
327 * Send a long message to the hardware. Timestamp is in microseconds.
328 * This blocks until a slot to send a message is free.
329 * Returns MIDI_SUCCESS or an error code
330 */
331INT32 MIDI_OUT_SendLongMessage(MidiDeviceHandle* handle, UBYTE* data, UINT32 size, UINT32 timestamp);
332
333#endif // USE_PLATFORM_MIDI_OUT
334
335#endif // PLATFORM_MIDI_INCLUDED
336