mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 12:09:14 +00:00
239 lines
8.2 KiB
C
239 lines
8.2 KiB
C
/*
|
|
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation. Oracle designates this
|
|
* particular file as subject to the "Classpath" exception as provided
|
|
* by Oracle in the LICENSE file that accompanied this code.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*/
|
|
|
|
//#define USE_ERROR
|
|
//#define USE_TRACE
|
|
|
|
#if USE_PLATFORM_MIDI_OUT == TRUE
|
|
|
|
#include "PLATFORM_API_MacOSX_MidiUtils.h"
|
|
|
|
char* MIDI_OUT_GetErrorStr(INT32 err) {
|
|
return (char *) MIDI_Utils_GetErrorMsg((int) err);
|
|
}
|
|
|
|
|
|
INT32 MIDI_OUT_GetNumDevices() {
|
|
return MIDI_Utils_GetNumDevices(MIDI_OUT);
|
|
}
|
|
|
|
|
|
INT32 MIDI_OUT_GetDeviceName(INT32 deviceID, char *name, UINT32 nameLength) {
|
|
return MIDI_Utils_GetDeviceName(MIDI_OUT, deviceID, name, nameLength);
|
|
}
|
|
|
|
|
|
INT32 MIDI_OUT_GetDeviceVendor(INT32 deviceID, char *name, UINT32 nameLength) {
|
|
return MIDI_Utils_GetDeviceVendor(MIDI_OUT, deviceID, name, nameLength);
|
|
}
|
|
|
|
|
|
INT32 MIDI_OUT_GetDeviceDescription(INT32 deviceID, char *name, UINT32 nameLength) {
|
|
return MIDI_Utils_GetDeviceDescription(MIDI_OUT, deviceID, name, nameLength);
|
|
}
|
|
|
|
|
|
INT32 MIDI_OUT_GetDeviceVersion(INT32 deviceID, char *name, UINT32 nameLength) {
|
|
return MIDI_Utils_GetDeviceVersion(MIDI_OUT, deviceID, name, nameLength);
|
|
}
|
|
|
|
|
|
/* *************************** MidiOutDevice implementation ***************************************** */
|
|
|
|
INT32 MIDI_OUT_OpenDevice(INT32 deviceID, MidiDeviceHandle** handle) {
|
|
TRACE1("MIDI_OUT_OpenDevice: deviceID: %d\n", (int) deviceID);
|
|
/* queue sizes are ignored for MIDI_OUT only (uses STREAMS) */
|
|
return MIDI_Utils_OpenDevice(MIDI_OUT, deviceID, (MacMidiDeviceHandle**) handle, 0, 0, 0);
|
|
}
|
|
|
|
INT32 MIDI_OUT_CloseDevice(MidiDeviceHandle* handle) {
|
|
TRACE0("MIDI_OUT_CloseDevice\n");
|
|
|
|
// issue a "SUSTAIN OFF" message to each MIDI channel, 0 to 15.
|
|
// "CONTROL CHANGE" is 176, "SUSTAIN CONTROLLER" is 64, and the value is 0.
|
|
// $$fb 2002-04-04: It is responsability of the application developer to
|
|
// leave the device in a consistent state. So I put this in comments
|
|
/*
|
|
for (channel = 0; channel < 16; channel++)
|
|
MIDI_OUT_SendShortMessage(deviceHandle, (unsigned char)(176 + channel),
|
|
(unsigned char)64, (unsigned char)0, (UINT32)-1);
|
|
*/
|
|
return MIDI_Utils_CloseDevice((MacMidiDeviceHandle*) handle);
|
|
}
|
|
|
|
|
|
INT64 MIDI_OUT_GetTimeStamp(MidiDeviceHandle* handle) {
|
|
return MIDI_Utils_GetTimeStamp((MacMidiDeviceHandle*) handle);
|
|
}
|
|
|
|
|
|
INT32 MIDI_OUT_SendShortMessage(MidiDeviceHandle* handle, UINT32 packedMsg, UINT32 timestamp) {
|
|
OSStatus err = noErr;
|
|
|
|
TRACE2("> MIDI_OUT_SendShortMessage %x, time: %d\n", (uint) packedMsg, (int) timestamp);
|
|
if (!handle) {
|
|
ERROR0("< ERROR: MIDI_OUT_SendShortMessage: handle is NULL\n");
|
|
return MIDI_INVALID_HANDLE;
|
|
}
|
|
|
|
MacMidiDeviceHandle* macHandle = (MacMidiDeviceHandle*) handle;
|
|
UInt8 mBuffers[100];
|
|
MIDIPacketList* packetList = (MIDIPacketList*) mBuffers;
|
|
MIDIPacket* packet;
|
|
UINT32 nData;
|
|
Byte data[3] = {packedMsg & 0xFF, (packedMsg >> 8) & 0xFF, (packedMsg >> 16) & 0xFF};
|
|
bool byteIsInvalid = FALSE;
|
|
|
|
packet = MIDIPacketListInit(packetList);
|
|
switch (data[0] & 0xF0) {
|
|
case 0x80: // Note off
|
|
case 0x90: // Note on
|
|
case 0xA0: // Aftertouch
|
|
case 0xB0: // Controller
|
|
case 0xE0: // Pitch wheel
|
|
nData = 3;
|
|
break;
|
|
|
|
case 0xC0: // Program change
|
|
case 0xD0: // Channel pressure
|
|
nData = 2;
|
|
break;
|
|
|
|
case 0xF0: {
|
|
// System common message
|
|
switch (data[0]) {
|
|
case 0xF0:
|
|
case 0xF7:
|
|
// System exclusive
|
|
fprintf(stderr, "%s: %d->internal error: sysex message status=0x%X while sending short message\n",
|
|
__FILE__, __LINE__, data[0]);
|
|
byteIsInvalid = TRUE;
|
|
break;
|
|
|
|
case 0xF1: // MTC quarter frame message
|
|
//fprintf(stderr, ">>>MIDI_OUT_SendShortMessage: MTC quarter frame message....\n");
|
|
nData = 2;
|
|
break;
|
|
case 0xF3: // Song select
|
|
//fprintf(stderr, ">>>MIDI_OUT_SendShortMessage: Song select....\n");
|
|
nData = 2;
|
|
break;
|
|
|
|
case 0xF2: // Song position pointer
|
|
//fprintf(stderr, ">>>MIDI_OUT_SendShortMessage: Song position pointer....\n");
|
|
nData = 3;
|
|
break;
|
|
|
|
case 0xF6: // Tune request
|
|
//fprintf(stderr, ">>>MIDI_OUT_SendShortMessage: Tune request....\n");
|
|
nData = 1;
|
|
break;
|
|
|
|
default:
|
|
// Invalid message
|
|
fprintf(stderr, "%s: %d->Invalid message: message status=0x%X while sending short message\n",
|
|
__FILE__, __LINE__, data[0]);
|
|
byteIsInvalid = TRUE;
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
default:
|
|
// This can't happen, but handle it anyway.
|
|
fprintf(stderr, "%s: %d->Invalid message: message status=0x%X while sending short message\n",
|
|
__FILE__, __LINE__, data[0]);
|
|
byteIsInvalid = TRUE;
|
|
break;
|
|
}
|
|
|
|
if (byteIsInvalid) return -1;
|
|
|
|
MIDIPacketListAdd(packetList, sizeof(mBuffers), packet, 0, nData, data);
|
|
err = MIDISend(macHandle->port, (MIDIEndpointRef) (intptr_t) handle->deviceHandle, packetList);
|
|
|
|
MIDI_CHECK_ERROR;
|
|
TRACE0("< MIDI_OUT_SendShortMessage\n");
|
|
return (err == noErr ? MIDI_SUCCESS : -1);
|
|
}
|
|
|
|
|
|
INT32 MIDI_OUT_SendLongMessage(MidiDeviceHandle* handle, UBYTE* data, UINT32 size, UINT32 timestamp) {
|
|
OSStatus err = noErr;
|
|
|
|
TRACE2("> MIDI_OUT_SendLongMessage size %d, time: %d\n", (int) size, (int) timestamp);
|
|
if (!handle || !data) {
|
|
ERROR0("< ERROR: MIDI_OUT_SendLongMessage: handle, or data is NULL\n");
|
|
return MIDI_INVALID_HANDLE;
|
|
}
|
|
if (size == 0) {
|
|
return MIDI_SUCCESS;
|
|
}
|
|
|
|
MacMidiDeviceHandle* macHandle = (MacMidiDeviceHandle*) handle;
|
|
UInt8 mBuffers[8196];
|
|
MIDIPacketList* packetList = (MIDIPacketList*) mBuffers;
|
|
MIDIPacket* packet = NULL;
|
|
UINT32 remaining = size;
|
|
UINT32 increment = 512;
|
|
UINT32 nData;
|
|
|
|
handle->isWaiting = TRUE;
|
|
|
|
while (remaining > 0) {
|
|
|
|
if (packet == NULL) {
|
|
packet = MIDIPacketListInit(packetList);
|
|
}
|
|
|
|
if (remaining > increment) {
|
|
nData = increment;
|
|
} else {
|
|
nData = remaining;
|
|
}
|
|
|
|
// Copies the bytes to our current packet.
|
|
if ((packet = MIDIPacketListAdd(packetList, sizeof(mBuffers), packet, 0, nData, (const Byte*) data)) == NULL) {
|
|
// Packet list is full, send it.
|
|
err = MIDISend(macHandle->port, (MIDIEndpointRef) (intptr_t) handle->deviceHandle, packetList);
|
|
if (err != noErr) {
|
|
break;
|
|
}
|
|
} else {
|
|
// Moves the data pointer to the next segment.
|
|
data += nData;
|
|
remaining -= nData;
|
|
packet = MIDIPacketNext(packet);
|
|
}
|
|
}
|
|
|
|
MIDI_CHECK_ERROR;
|
|
handle->isWaiting = FALSE;
|
|
TRACE0("< MIDI_OUT_SendLongMessage\n");
|
|
return (err == noErr ? MIDI_SUCCESS : -1);
|
|
}
|
|
|
|
#endif /* USE_PLATFORM_MIDI_OUT */
|