Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/macosx/native/libjsound/PLATFORM_API_MacOSX_MidiOut.c
41152 views
1
/*
2
* Copyright (c) 2003, 2012, 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
//#define USE_ERROR
27
//#define USE_TRACE
28
29
#if USE_PLATFORM_MIDI_OUT == TRUE
30
31
#include "PLATFORM_API_MacOSX_MidiUtils.h"
32
33
char* MIDI_OUT_GetErrorStr(INT32 err) {
34
return (char *) MIDI_Utils_GetErrorMsg((int) err);
35
}
36
37
38
INT32 MIDI_OUT_GetNumDevices() {
39
return MIDI_Utils_GetNumDevices(MIDI_OUT);
40
}
41
42
43
INT32 MIDI_OUT_GetDeviceName(INT32 deviceID, char *name, UINT32 nameLength) {
44
return MIDI_Utils_GetDeviceName(MIDI_OUT, deviceID, name, nameLength);
45
}
46
47
48
INT32 MIDI_OUT_GetDeviceVendor(INT32 deviceID, char *name, UINT32 nameLength) {
49
return MIDI_Utils_GetDeviceVendor(MIDI_OUT, deviceID, name, nameLength);
50
}
51
52
53
INT32 MIDI_OUT_GetDeviceDescription(INT32 deviceID, char *name, UINT32 nameLength) {
54
return MIDI_Utils_GetDeviceDescription(MIDI_OUT, deviceID, name, nameLength);
55
}
56
57
58
INT32 MIDI_OUT_GetDeviceVersion(INT32 deviceID, char *name, UINT32 nameLength) {
59
return MIDI_Utils_GetDeviceVersion(MIDI_OUT, deviceID, name, nameLength);
60
}
61
62
63
/* *************************** MidiOutDevice implementation ***************************************** */
64
65
INT32 MIDI_OUT_OpenDevice(INT32 deviceID, MidiDeviceHandle** handle) {
66
TRACE1("MIDI_OUT_OpenDevice: deviceID: %d\n", (int) deviceID);
67
/* queue sizes are ignored for MIDI_OUT only (uses STREAMS) */
68
return MIDI_Utils_OpenDevice(MIDI_OUT, deviceID, (MacMidiDeviceHandle**) handle, 0, 0, 0);
69
}
70
71
INT32 MIDI_OUT_CloseDevice(MidiDeviceHandle* handle) {
72
TRACE0("MIDI_OUT_CloseDevice\n");
73
74
// issue a "SUSTAIN OFF" message to each MIDI channel, 0 to 15.
75
// "CONTROL CHANGE" is 176, "SUSTAIN CONTROLLER" is 64, and the value is 0.
76
// $$fb 2002-04-04: It is responsability of the application developer to
77
// leave the device in a consistent state. So I put this in comments
78
/*
79
for (channel = 0; channel < 16; channel++)
80
MIDI_OUT_SendShortMessage(deviceHandle, (unsigned char)(176 + channel),
81
(unsigned char)64, (unsigned char)0, (UINT32)-1);
82
*/
83
return MIDI_Utils_CloseDevice((MacMidiDeviceHandle*) handle);
84
}
85
86
87
INT64 MIDI_OUT_GetTimeStamp(MidiDeviceHandle* handle) {
88
return MIDI_Utils_GetTimeStamp((MacMidiDeviceHandle*) handle);
89
}
90
91
92
INT32 MIDI_OUT_SendShortMessage(MidiDeviceHandle* handle, UINT32 packedMsg, UINT32 timestamp) {
93
OSStatus err = noErr;
94
95
TRACE2("> MIDI_OUT_SendShortMessage %x, time: %d\n", (uint) packedMsg, (int) timestamp);
96
if (!handle) {
97
ERROR0("< ERROR: MIDI_OUT_SendShortMessage: handle is NULL\n");
98
return MIDI_INVALID_HANDLE;
99
}
100
101
MacMidiDeviceHandle* macHandle = (MacMidiDeviceHandle*) handle;
102
UInt8 mBuffers[100];
103
MIDIPacketList* packetList = (MIDIPacketList*) mBuffers;
104
MIDIPacket* packet;
105
UINT32 nData;
106
Byte data[3] = {packedMsg & 0xFF, (packedMsg >> 8) & 0xFF, (packedMsg >> 16) & 0xFF};
107
bool byteIsInvalid = FALSE;
108
109
packet = MIDIPacketListInit(packetList);
110
switch (data[0] & 0xF0) {
111
case 0x80: // Note off
112
case 0x90: // Note on
113
case 0xA0: // Aftertouch
114
case 0xB0: // Controller
115
case 0xE0: // Pitch wheel
116
nData = 3;
117
break;
118
119
case 0xC0: // Program change
120
case 0xD0: // Channel pressure
121
nData = 2;
122
break;
123
124
case 0xF0: {
125
// System common message
126
switch (data[0]) {
127
case 0xF0:
128
case 0xF7:
129
// System exclusive
130
fprintf(stderr, "%s: %d->internal error: sysex message status=0x%X while sending short message\n",
131
__FILE__, __LINE__, data[0]);
132
byteIsInvalid = TRUE;
133
break;
134
135
case 0xF1: // MTC quarter frame message
136
//fprintf(stderr, ">>>MIDI_OUT_SendShortMessage: MTC quarter frame message....\n");
137
nData = 2;
138
break;
139
case 0xF3: // Song select
140
//fprintf(stderr, ">>>MIDI_OUT_SendShortMessage: Song select....\n");
141
nData = 2;
142
break;
143
144
case 0xF2: // Song position pointer
145
//fprintf(stderr, ">>>MIDI_OUT_SendShortMessage: Song position pointer....\n");
146
nData = 3;
147
break;
148
149
case 0xF6: // Tune request
150
//fprintf(stderr, ">>>MIDI_OUT_SendShortMessage: Tune request....\n");
151
nData = 1;
152
break;
153
154
default:
155
// Invalid message
156
fprintf(stderr, "%s: %d->Invalid message: message status=0x%X while sending short message\n",
157
__FILE__, __LINE__, data[0]);
158
byteIsInvalid = TRUE;
159
break;
160
}
161
break;
162
}
163
164
default:
165
// This can't happen, but handle it anyway.
166
fprintf(stderr, "%s: %d->Invalid message: message status=0x%X while sending short message\n",
167
__FILE__, __LINE__, data[0]);
168
byteIsInvalid = TRUE;
169
break;
170
}
171
172
if (byteIsInvalid) return -1;
173
174
MIDIPacketListAdd(packetList, sizeof(mBuffers), packet, 0, nData, data);
175
err = MIDISend(macHandle->port, (MIDIEndpointRef) (intptr_t) handle->deviceHandle, packetList);
176
177
MIDI_CHECK_ERROR;
178
TRACE0("< MIDI_OUT_SendShortMessage\n");
179
return (err == noErr ? MIDI_SUCCESS : -1);
180
}
181
182
183
INT32 MIDI_OUT_SendLongMessage(MidiDeviceHandle* handle, UBYTE* data, UINT32 size, UINT32 timestamp) {
184
OSStatus err = noErr;
185
186
TRACE2("> MIDI_OUT_SendLongMessage size %d, time: %d\n", (int) size, (int) timestamp);
187
if (!handle || !data) {
188
ERROR0("< ERROR: MIDI_OUT_SendLongMessage: handle, or data is NULL\n");
189
return MIDI_INVALID_HANDLE;
190
}
191
if (size == 0) {
192
return MIDI_SUCCESS;
193
}
194
195
MacMidiDeviceHandle* macHandle = (MacMidiDeviceHandle*) handle;
196
UInt8 mBuffers[8196];
197
MIDIPacketList* packetList = (MIDIPacketList*) mBuffers;
198
MIDIPacket* packet = NULL;
199
UINT32 remaining = size;
200
UINT32 increment = 512;
201
UINT32 nData;
202
203
handle->isWaiting = TRUE;
204
205
while (remaining > 0) {
206
207
if (packet == NULL) {
208
packet = MIDIPacketListInit(packetList);
209
}
210
211
if (remaining > increment) {
212
nData = increment;
213
} else {
214
nData = remaining;
215
}
216
217
// Copies the bytes to our current packet.
218
if ((packet = MIDIPacketListAdd(packetList, sizeof(mBuffers), packet, 0, nData, (const Byte*) data)) == NULL) {
219
// Packet list is full, send it.
220
err = MIDISend(macHandle->port, (MIDIEndpointRef) (intptr_t) handle->deviceHandle, packetList);
221
if (err != noErr) {
222
break;
223
}
224
} else {
225
// Moves the data pointer to the next segment.
226
data += nData;
227
remaining -= nData;
228
packet = MIDIPacketNext(packet);
229
}
230
}
231
232
MIDI_CHECK_ERROR;
233
handle->isWaiting = FALSE;
234
TRACE0("< MIDI_OUT_SendLongMessage\n");
235
return (err == noErr ? MIDI_SUCCESS : -1);
236
}
237
238
#endif /* USE_PLATFORM_MIDI_OUT */
239
240