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 |
58 | typedef enum { |
59 | SHORT_MESSAGE = 0, |
60 | LONG_MESSAGE = 1 |
61 | } MidiMessageType; |
62 | |
63 | // MIDI message object |
64 | typedef 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 */ |
84 | char* MIDI_IN_InternalGetErrorString(INT32 err); |
85 | char* MIDI_OUT_InternalGetErrorString(INT32 err); |
86 | |
87 | |
88 | #if USE_MIDI_QUEUE == TRUE |
89 | /* |
90 | * Native MIDI message circular buffer |
91 | */ |
92 | typedef 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() |
103 | typedef 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 | */ |
120 | void* MIDI_CreateLock(); |
121 | void MIDI_DestroyLock(void* lock); |
122 | |
123 | /* Blocks until this lock can be gotten. |
124 | * Nop if lock is NULL */ |
125 | void MIDI_Lock(void* lock); |
126 | |
127 | /* Releases this lock */ |
128 | void MIDI_Unlock(void* lock); |
129 | |
130 | MidiMessageQueue* MIDI_CreateQueue(int capacity); |
131 | void 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 |
134 | int MIDI_QueueAddShort(MidiMessageQueue* queue, UINT32 packedMsg, INT64 timestamp, int overwrite); |
135 | int MIDI_QueueAddLong(MidiMessageQueue* queue, UBYTE* data, UINT32 size, |
136 | INT32 sysexIndex, INT64 timestamp, int overwrite); |
137 | |
138 | // returns NULL if no messages in queue. |
139 | MidiMessage* MIDI_QueueRead(MidiMessageQueue* queue); |
140 | // message will be removed from queue. |
141 | void MIDI_QueueRemove(MidiMessageQueue* queue, INT32 onlyLocked); |
142 | void 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 | */ |
166 | char* MIDI_IN_GetErrorStr(INT32 err); |
167 | |
168 | |
169 | /* |
170 | * Get the number of MIDI IN devices on the system. |
171 | */ |
172 | INT32 MIDI_IN_GetNumDevices(); |
173 | |
174 | /* |
175 | * Get the name of the device with this id |
176 | * Returns MIDI_SUCCESS or an error code |
177 | */ |
178 | INT32 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 | */ |
184 | INT32 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 | */ |
190 | INT32 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 | */ |
196 | INT32 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 | */ |
203 | INT32 MIDI_IN_OpenDevice(INT32 deviceID, MidiDeviceHandle** handle); |
204 | |
205 | /* |
206 | * Close the device handle. |
207 | * Returns MIDI_SUCCESS or an error code |
208 | */ |
209 | INT32 MIDI_IN_CloseDevice(MidiDeviceHandle* handle); |
210 | |
211 | /* |
212 | * Start the device with this handle. |
213 | * Returns MIDI_SUCCESS or an error code |
214 | */ |
215 | INT32 MIDI_IN_StartDevice(MidiDeviceHandle* handle); |
216 | |
217 | /* |
218 | * Stop the device with this handle. |
219 | * Returns MIDI_SUCCESS or an error code |
220 | */ |
221 | INT32 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 | */ |
227 | INT64 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 | */ |
237 | MidiMessage* MIDI_IN_GetMessage(MidiDeviceHandle* handle); |
238 | |
239 | /* |
240 | * Put a message, which was taken |
241 | * out of the queue, back into the queue. |
242 | */ |
243 | void 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 | */ |
266 | char* MIDI_OUT_GetErrorStr(INT32 err); |
267 | |
268 | |
269 | /* |
270 | * Get the number of MIDI OUT devices on the system. |
271 | */ |
272 | INT32 MIDI_OUT_GetNumDevices(); |
273 | |
274 | /* |
275 | * Get the name of the device with this id |
276 | * Returns MIDI_SUCCESS or an error code |
277 | */ |
278 | INT32 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 | */ |
284 | INT32 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 | */ |
290 | INT32 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 | */ |
296 | INT32 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 | */ |
303 | INT32 MIDI_OUT_OpenDevice(INT32 deviceID, MidiDeviceHandle** handle); |
304 | |
305 | /* |
306 | * Close the device handle. |
307 | * Returns MIDI_SUCCESS or an error code |
308 | */ |
309 | INT32 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 | */ |
316 | INT64 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 | */ |
324 | INT32 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 | */ |
331 | INT32 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 | |