/*
 * 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.
 */

/*
**
**    Overview:
**      Implementation of the functions used for both MIDI in and MIDI out.
**
**      Java package com.sun.media.sound defines the AbstractMidiDevice class
**      which encapsulates functionalities shared by both MidiInDevice and
**      MidiOutDevice classes in the same package.
**
**      The Java layer classes MidiInDevice and MidiOutDevice in turn map to
**      the MIDIEndpointRef data type in the CoreMIDI framework, which
**      represents a source or destination for a standard 16-channel MIDI data
**      stream.
*/
/*****************************************************************************/

//#define USE_ERROR
//#define USE_TRACE

/* Use THIS_FILE when it is available. */
#ifndef THIS_FILE
    #define THIS_FILE __FILE__
#endif

#if (USE_PLATFORM_MIDI_IN == TRUE) || (USE_PLATFORM_MIDI_OUT == TRUE)

#include "PLATFORM_API_MacOSX_MidiUtils.h"
#include <pthread.h>
#include <assert.h>

// Constant character string definitions of CoreMIDI's corresponding error codes.

static const char* strMIDIInvalidClient =
                        "An invalid MIDIClientRef was passed.";
static const char* strMIDIInvalidPort =
                        "An invalid MIDIPortRef was passed.";
static const char* strMIDIWrongEndpointType =
                        "A source endpoint was passed to a function expecting a destination, or vice versa.";
static const char* strMIDINoConnection =
                        "Attempt to close a non-existant connection.";
static const char* strMIDIUnknownEndpoint =
                        "An invalid MIDIEndpointRef was passed.";
static const char* strMIDIUnknownProperty =
                        "Attempt to query a property not set on the object.";
static const char* strMIDIWrongPropertyType =
                        "Attempt to set a property with a value not of the correct type.";
static const char* strMIDINoCurrentSetup =
                        "Internal error; there is no current MIDI setup object.";
static const char* strMIDIMessageSendErr =
                        "Communication with MIDIServer failed.";
static const char* strMIDIServerStartErr =
                        "Unable to start MIDIServer.";
static const char* strMIDISetupFormatErr =
                        "Unable to read the saved state.";
static const char* strMIDIWrongThread =
                        "A driver is calling a non-I/O function in the server from a thread other than"
                        "the server's main thread.";
static const char* strMIDIObjectNotFound =
                        "The requested object does not exist.";
static const char* strMIDIIDNotUnique =
                        "Attempt to set a non-unique kMIDIPropertyUniqueID on an object.";

static const char* midi_strerror(int err) {
/*
    @enum           Error Constants
    @abstract       The error constants unique to Core MIDI.
    @discussion     These are the error constants that are unique to Core MIDI. Note that Core MIDI
                    functions may return other codes that are not listed here.
*/
    const char* strerr;

    switch (err) {
    case kMIDIInvalidClient:
        strerr = strMIDIInvalidClient;
        break;
    case kMIDIInvalidPort:
        strerr = strMIDIInvalidPort;
        break;
    case kMIDIWrongEndpointType:
        strerr = strMIDIWrongEndpointType;
        break;
    case kMIDINoConnection:
        strerr = strMIDINoConnection;
        break;
    case kMIDIUnknownEndpoint:
        strerr = strMIDIUnknownEndpoint;
        break;
    case kMIDIUnknownProperty:
        strerr = strMIDIUnknownProperty;
        break;
    case kMIDIWrongPropertyType:
        strerr = strMIDIWrongPropertyType;
        break;
    case kMIDINoCurrentSetup:
        strerr = strMIDINoCurrentSetup;
        break;
    case kMIDIMessageSendErr:
        strerr = strMIDIMessageSendErr;
        break;
    case kMIDIServerStartErr:
        strerr = strMIDIServerStartErr;
        break;
    case kMIDISetupFormatErr:
        strerr = strMIDISetupFormatErr;
        break;
    case kMIDIWrongThread:
        strerr = strMIDIWrongThread;
        break;
    case kMIDIObjectNotFound:
        strerr = strMIDIObjectNotFound;
        break;
    case kMIDIIDNotUnique:
        strerr = strMIDIIDNotUnique;
        break;
    default:
        strerr = "Unknown error.";
        break;
    }
    return strerr;
}

const char* MIDI_Utils_GetErrorMsg(int err) {
    return midi_strerror(err);
}


void MIDI_Utils_PrintError(int err) {
#ifdef USE_ERROR
    const char* s = MIDI_Utils_GetErrorMsg(err);
    if (s != NULL) {
        fprintf(stderr, "%s\n", s);
    }
#endif
}


// Note direction is either MIDI_IN or MIDI_OUT.
INT32 MIDI_Utils_GetNumDevices(int direction) {
    int num_endpoints;
    if (direction == MIDI_IN) {
        num_endpoints = MIDIGetNumberOfSources();
    //fprintf(stdout, "MIDIGetNumberOfSources() returns %d\n", num_endpoints);
    } else if (direction == MIDI_OUT) {
        num_endpoints = MIDIGetNumberOfDestinations();
        //printf(stdout, "MIDIGetNumberOfDestinations() returns %d\n", num_endpoints);
    } else {
        assert((direction == MIDI_IN || direction == MIDI_OUT));
        num_endpoints = 0;
    }
    return (INT32) num_endpoints;
}

// Wraps calls to CFStringGetCStringPtr and CFStringGetCString to make sure
// we extract the c characters into the buffer and null-terminate it.
static void CFStringExtractCString(CFStringRef cfs, char* buffer, UINT32 bufferSize, CFStringEncoding encoding) {
    const char* ptr = CFStringGetCStringPtr(cfs, encoding);
    if (ptr) {
        strlcpy(buffer, ptr, bufferSize);
    } else {
        if (! CFStringGetCString(cfs, buffer, bufferSize, encoding)) {
            // There's an error in conversion, make sure we null-terminate the buffer.
            buffer[bufferSize - 1] = '\0';
        }
    }
}

//
// @see com.sun.media.sound.AbstractMidiDeviceProvider.getDeviceInfo().
static int getEndpointProperty(int direction, INT32 deviceID, char *buffer, int bufferLength, CFStringRef propertyID) {

    if (deviceID < 0) {
        return MIDI_INVALID_DEVICEID;
    }

    MIDIEndpointRef endpoint;

    if (direction == MIDI_IN) {
        endpoint = MIDIGetSource(deviceID);
    } else if (direction == MIDI_OUT) {
        endpoint = MIDIGetDestination(deviceID);
    } else {
        return MIDI_INVALID_ARGUMENT;
    }

    if (!endpoint) {
        return MIDI_INVALID_DEVICEID;
    }

    int status = MIDI_SUCCESS;
    if (propertyID == kMIDIPropertyDriverVersion) {
        SInt32 driverVersion;
        status = MIDIObjectGetIntegerProperty(endpoint, kMIDIPropertyDriverVersion, &driverVersion);
        if (status != MIDI_SUCCESS) return status;
        snprintf(buffer,
                 bufferLength,
                 "%d",
                 (int) driverVersion);
    }
    else {
        CFStringRef pname;
        status = MIDIObjectGetStringProperty(endpoint, propertyID, &pname);
        if (status != MIDI_SUCCESS) return status;
        CFStringExtractCString(pname, buffer, bufferLength, 0);
    }
    return MIDI_ERROR_NONE;
}

// A simple utility which encapsulates CoreAudio's HostTime APIs.
// It returns the current host time in nanoseconds which when subtracted from
// a previous getCurrentTimeInNanos() result produces the delta in nanos.
static UInt64 getCurrentTimeInNanos() {
    UInt64 hostTime = AudioGetCurrentHostTime();
    UInt64 nanos = AudioConvertHostTimeToNanos(hostTime);
    return nanos;
}


INT32 MIDI_Utils_GetDeviceName(int direction, INT32 deviceID, char *name, UINT32 bufferLength) {
    return getEndpointProperty(direction, deviceID, name, bufferLength, kMIDIPropertyName);
}


INT32 MIDI_Utils_GetDeviceVendor(int direction, INT32 deviceID, char *name, UINT32 bufferLength) {
    return getEndpointProperty(direction, deviceID, name, bufferLength, kMIDIPropertyManufacturer);
}


INT32 MIDI_Utils_GetDeviceDescription(int direction, INT32 deviceID, char *name, UINT32 bufferLength) {
    return getEndpointProperty(direction, deviceID, name, bufferLength, kMIDIPropertyDisplayName);
}


INT32 MIDI_Utils_GetDeviceVersion(int direction, INT32 deviceID, char *name, UINT32 bufferLength) {
    return getEndpointProperty(direction, deviceID, name, bufferLength, kMIDIPropertyDriverVersion);
}


static MIDIClientRef client = (MIDIClientRef) NULL;
static MIDIPortRef inPort = (MIDIPortRef) NULL;
static MIDIPortRef outPort = (MIDIPortRef) NULL;

// Each MIDIPacket can contain more than one midi messages.
// This function processes the packet and adds the messages to the specified message queue.
// @see also src/share/native/com/sun/media/sound/PlatformMidi.h.
static void processMessagesForPacket(const MIDIPacket* packet, MacMidiDeviceHandle* handle) {
    const UInt8* data;
    UInt16 length;
    UInt8 byte;
    UInt8 pendingMessageStatus;
    UInt8 pendingData[2];
    UInt16 pendingDataIndex, pendingDataLength;
    UINT32 packedMsg;
    MIDITimeStamp ts = packet->timeStamp;

    pendingMessageStatus = 0;
    pendingDataIndex = pendingDataLength = 0;

    data = packet->data;
    length = packet->length;
    while (length--) {
        bool byteIsInvalid = FALSE;

        byte = *data++;
        packedMsg = byte;

        if (byte >= 0xF8) {
            // Each RealTime Category message (ie, Status of 0xF8 to 0xFF) consists of only 1 byte, the Status.
            // Except that 0xFD is an invalid status code.
            //
            // 0xF8 -> Midi clock
            // 0xF9 -> Midi tick
            // 0xFA -> Midi start
            // 0xFB -> Midi continue
            // 0xFC -> Midi stop
            // 0xFE -> Active sense
            // 0xFF -> Reset
            if (byte == 0xFD) {
                byteIsInvalid = TRUE;
            } else {
                pendingDataLength = 0;
            }
        } else {
            if (byte < 0x80) {
                // Not a status byte -- check our history.
                if (handle->readingSysExData) {
                    CFDataAppendBytes(handle->readingSysExData, &byte, 1);

                } else if (pendingDataIndex < pendingDataLength) {
                    pendingData[pendingDataIndex] = byte;
                    pendingDataIndex++;

                    if (pendingDataIndex == pendingDataLength) {
                        // This message is now done -- do the final processing.
                        if (pendingDataLength == 2) {
                            packedMsg = pendingMessageStatus | pendingData[0] << 8 | pendingData[1] << 16;
                        } else if (pendingDataLength == 1) {
                            packedMsg = pendingMessageStatus | pendingData[0] << 8;
                        } else {
                            fprintf(stderr, "%s: %d->internal error: pendingMessageStatus=0x%X, pendingDataLength=%d\n",
                                    THIS_FILE, __LINE__, pendingMessageStatus, pendingDataLength);
                            byteIsInvalid = TRUE;
                        }
                        pendingDataLength = 0;
                    }
                } else {
                    // Skip this byte -- it is invalid.
                    byteIsInvalid = TRUE;
                }
            } else {
                if (handle->readingSysExData /* && (byte == 0xF7) */) {
                    // We have reached the end of system exclusive message -- send it finally.
                    const UInt8* bytes = CFDataGetBytePtr(handle->readingSysExData);
                    CFIndex size = CFDataGetLength(handle->readingSysExData);
                    MIDI_QueueAddLong(handle->h.queue,
                                      (UBYTE*) bytes,
                                      (UINT32) size,
                                      0, // Don't care, windowish porting only.
                                      (INT64) (AudioConvertHostTimeToNanos(ts) + 500) / 1000,
                                      TRUE);
                    CFRelease(handle->readingSysExData);
                    handle->readingSysExData = NULL;
                }

                pendingMessageStatus = byte;
                pendingDataLength = 0;
                pendingDataIndex = 0;

                switch (byte & 0xF0) {
                    case 0x80:    // Note off
                    case 0x90:    // Note on
                    case 0xA0:    // Aftertouch
                    case 0xB0:    // Controller
                    case 0xE0:    // Pitch wheel
                        pendingDataLength = 2;
                        break;

                    case 0xC0:    // Program change
                    case 0xD0:    // Channel pressure
                        pendingDataLength = 1;
                        break;

                    case 0xF0: {
                        // System common message
                        switch (byte) {
                        case 0xF0:
                            // System exclusive
                            // Allocates a CFMutableData reference to accumulate the SysEx data until EOX (0xF7) is reached.
                            handle->readingSysExData = CFDataCreateMutable(NULL, 0);
                            break;

                        case 0xF7:
                            // System exclusive ends--already handled above.
                            // But if this is showing up outside of sysex, it's invalid.
                            byteIsInvalid = TRUE;
                            break;

                        case 0xF1:    // MTC quarter frame message
                        case 0xF3:    // Song select
                            pendingDataLength = 1;
                            break;

                        case 0xF2:    // Song position pointer
                            pendingDataLength = 2;
                            break;

                        case 0xF6:    // Tune request
                            pendingDataLength = 0;
                            break;

                        default:
                            // Invalid message
                            byteIsInvalid = TRUE;
                            break;
                        }
                        break;
                    }

                    default:
                        // This can't happen, but handle it anyway.
                        byteIsInvalid = TRUE;
                        break;
                }
            }
        }
        if (byteIsInvalid) continue;

        // If the byte is valid and pendingDataLength is 0, we are ready to send the message.
        if (pendingDataLength == 0) {
            MIDI_QueueAddShort(handle->h.queue, packedMsg, (INT64) (AudioConvertHostTimeToNanos(ts) + 500) / 1000, TRUE);
        }
    }
}

static void midiReadProc(const MIDIPacketList* packetList, void* refCon, void* connRefCon) {
    unsigned int i;
    const MIDIPacket* packet;
    MacMidiDeviceHandle* handle = (MacMidiDeviceHandle*) connRefCon;

    packet = packetList->packet;
    for (i = 0; i < packetList->numPackets; ++i) {
        processMessagesForPacket(packet, handle);
        packet = MIDIPacketNext(packet);
    }

    // Notify the waiting thread that there's data available.
    if (handle) {
        MIDI_SignalConditionVariable(handle->h.platformData);
    }
}

static void midiInit() {
    if (client) {
        return;
    }

    OSStatus err = noErr;

    err = MIDIClientCreate(CFSTR("MIDI Client"), NULL, NULL, &client);
    if (err != noErr) { goto Exit; }

    // This just creates an input port through which the client may receive
    // incoming MIDI messages from any MIDI source.
    err = MIDIInputPortCreate(client, CFSTR("MIDI Input Port"), midiReadProc, NULL, &inPort);
    if (err != noErr) { goto Exit; }

    err = MIDIOutputPortCreate(client, CFSTR("MIDI Output Port"), &outPort);
    if (err != noErr) { goto Exit; }

Exit:
    if (err != noErr) {
        const char* s = MIDI_Utils_GetErrorMsg(err);
        if (s != NULL) {
            printf("%s\n", s);
        }
    }
}


INT32 MIDI_Utils_OpenDevice(int direction, INT32 deviceID, MacMidiDeviceHandle** handle,
                            int num_msgs, int num_long_msgs,
                            size_t lm_size)
{
    midiInit();

    int err = MIDI_ERROR_NONE;
    MIDIEndpointRef endpoint = (MIDIEndpointRef) NULL;

    TRACE0("MIDI_Utils_OpenDevice\n");

    (*handle) = (MacMidiDeviceHandle*) malloc(sizeof(MacMidiDeviceHandle));
    if (!(*handle)) {
        ERROR0("ERROR: MIDI_Utils_OpenDevice: out of memory\n");
        return MIDI_OUT_OF_MEMORY;
    }
    memset(*handle, 0, sizeof(MacMidiDeviceHandle));

    // Create the infrastructure for MIDI in/out, and after that,
    // get the device's endpoint.
    if (direction == MIDI_IN) {
        // Create queue and the pthread condition variable.
        (*handle)->h.queue = MIDI_CreateQueue(num_msgs);
        (*handle)->h.platformData = MIDI_CreateConditionVariable();
        if (!(*handle)->h.queue || !(*handle)->h.platformData) {
            ERROR0("< ERROR: MIDI_IN_OpenDevice: could not create queue or condition variable\n");
            free(*handle);
            (*handle) = NULL;
            return MIDI_OUT_OF_MEMORY;
        }
        endpoint = MIDIGetSource(deviceID);
        (*handle)->port = inPort;
    } else if (direction == MIDI_OUT) {
        endpoint = MIDIGetDestination(deviceID);
        (*handle)->port = outPort;
    }

    if (!endpoint) {
        // An error occurred.
        free(*handle);
        return MIDI_INVALID_DEVICEID;
    }
    (*handle)->h.deviceHandle = (void*) (intptr_t) endpoint;
    (*handle)->h.startTime = getCurrentTimeInNanos();
    (*handle)->direction = direction;
    (*handle)->deviceID = deviceID;

    TRACE0("MIDI_Utils_OpenDevice: succeeded\n");
    return err;
}


INT32 MIDI_Utils_CloseDevice(MacMidiDeviceHandle* handle) {
    int err = MIDI_ERROR_NONE;
    bool midiIn = (handle->direction == MIDI_IN);

    TRACE0("> MIDI_Utils_CloseDevice\n");
    if (!handle) {
        ERROR0("< ERROR: MIDI_Utils_CloseDevice: handle is NULL\n");
        return MIDI_INVALID_HANDLE;
    }
    if (!handle->h.deviceHandle) {
        ERROR0("< ERROR: MIDI_Utils_CloseDevice: native handle is NULL\n");
        return MIDI_INVALID_HANDLE;
    }
    handle->isStarted = FALSE;
    handle->h.deviceHandle = NULL;

    if (midiIn) {
        if (handle->h.queue != NULL) {
            MidiMessageQueue* queue = handle->h.queue;
            handle->h.queue = NULL;
            MIDI_DestroyQueue(queue);
        }
        if (handle->h.platformData) {
            MIDI_DestroyConditionVariable(handle->h.platformData);
        }
    }
    free(handle);

    TRACE0("< MIDI_Utils_CloseDevice: succeeded\n");
    return err;
}


INT32 MIDI_Utils_StartDevice(MacMidiDeviceHandle* handle) {
    OSStatus err = noErr;

    if (!handle || !handle->h.deviceHandle) {
        ERROR0("ERROR: MIDI_Utils_StartDevice: handle or native is NULL\n");
        return MIDI_INVALID_HANDLE;
    }

    // Clears all the events from the queue.
    MIDI_QueueClear(handle->h.queue);

    if (!handle->isStarted) {
        /* set the flag that we can now receive messages */
        handle->isStarted = TRUE;

        if (handle->direction == MIDI_IN) {
            // The handle->h.platformData field contains the (pthread_cond_t*)
            // associated with the source of the MIDI input stream, and is
            // used in the CoreMIDI's callback to signal the arrival of new
            // data.
            //
            // Similarly, handle->h.queue is used in the CoreMDID's callback
            // to dispatch the incoming messages to the appropriate queue.
            //
            err = MIDIPortConnectSource(inPort, (MIDIEndpointRef) (intptr_t) (handle->h.deviceHandle), (void*) handle);
        } else if (handle->direction == MIDI_OUT) {
            // Unschedules previous-sent packets.
            err = MIDIFlushOutput((MIDIEndpointRef) (intptr_t) handle->h.deviceHandle);
        }

        MIDI_CHECK_ERROR;
    }
    return MIDI_SUCCESS; /* don't fail */
}


INT32 MIDI_Utils_StopDevice(MacMidiDeviceHandle* handle) {
    OSStatus err = noErr;

    if (!handle || !handle->h.deviceHandle) {
        ERROR0("ERROR: MIDI_Utils_StopDevice: handle or native handle is NULL\n");
        return MIDI_INVALID_HANDLE;
    }

    if (handle->isStarted) {
        /* set the flag that we don't want to receive messages anymore */
        handle->isStarted = FALSE;

        if (handle->direction == MIDI_IN) {
            err = MIDIPortDisconnectSource(inPort, (MIDIEndpointRef) (intptr_t) (handle->h.deviceHandle));
        } else if (handle->direction == MIDI_OUT) {
            // Unschedules previously-sent packets.
            err = MIDIFlushOutput((MIDIEndpointRef) (intptr_t) handle->h.deviceHandle);
        }

        MIDI_CHECK_ERROR;
    }
    return MIDI_SUCCESS;
}


INT64 MIDI_Utils_GetTimeStamp(MacMidiDeviceHandle* handle) {

    if (!handle || !handle->h.deviceHandle) {
        ERROR0("ERROR: MIDI_Utils_GetTimeStamp: handle or native handle is NULL\n");
        return (INT64) -1; /* failure */
    }

    UInt64 delta = getCurrentTimeInNanos() - handle->h.startTime;
    return (INT64) ((delta + 500) / 1000);
}


/***************************************************************************/
/*            Condition Variable Support for Mac OS X Port                 */
/*                                                                         */
/* This works with the Native Locking Support defined below.  We are using */
/* POSIX pthread_cond_t/pthread_mutex_t to do locking and synchronization. */
/*                                                                         */
/* For MidiDeviceHandle* handle, the mutex reference is stored as handle-> */
/* queue->lock while the condition variabale reference is stored as handle */
/* ->platformData.                                                         */
/***************************************************************************/

// Called from Midi_Utils_Opendevice(...) to create a condition variable
// used to synchronize between the receive thread created by the CoreMIDI
// and the Java-initiated MidiInDevice run loop.
void* MIDI_CreateConditionVariable() {
    pthread_cond_t* cond = (pthread_cond_t*) malloc(sizeof(pthread_cond_t));
    pthread_cond_init(cond, NULL);
    return (void*) cond;
}

void MIDI_DestroyConditionVariable(void* cond) {
    while (pthread_cond_destroy((pthread_cond_t*) cond) == EBUSY) {
        pthread_cond_broadcast((pthread_cond_t*) cond);
        sched_yield();
    }
    return;
}

// Called from MIDI_IN_GetMessage(...) to wait for MIDI messages to become
// available via delivery from the CoreMIDI receive thread
void MIDI_WaitOnConditionVariable(void* cond, void* lock) {
    if (cond && lock) {
        pthread_mutex_lock(lock);
        pthread_cond_wait((pthread_cond_t*) cond, (pthread_mutex_t*) lock);
        pthread_mutex_unlock(lock);
    }
    return;
}

// Called from midiReadProc(...) to notify the waiting thread to unblock on
// the condition variable.
void MIDI_SignalConditionVariable(void* cond) {
    if (cond) {
        pthread_cond_signal((pthread_cond_t*) cond);
    }
    return;
}


/**************************************************************************/
/*                     Native Locking Support                             */
/*                                                                        */
/* @see src/share/natve/com/sun/media/sound/PlatformMidi.c which contains */
/* utility functions for platform midi support where the section of code  */
/* for MessageQueue implementation calls out to these functions.          */
/**************************************************************************/

void* MIDI_CreateLock() {
    pthread_mutex_t* lock = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t));
    pthread_mutex_init(lock, NULL);
    TRACE0("MIDI_CreateLock\n");
    return (void *)lock;
}

void MIDI_DestroyLock(void* lock) {
    if (lock) {
        pthread_mutex_destroy((pthread_mutex_t*) lock);
        free(lock);
        TRACE0("MIDI_DestroyLock\n");
    }
}

void MIDI_Lock(void* lock) {
    if (lock) {
        pthread_mutex_lock((pthread_mutex_t*) lock);
    }
}

void MIDI_Unlock(void* lock) {
    if (lock) {
        pthread_mutex_unlock((pthread_mutex_t*) lock);
    }
}


#endif // USE_PLATFORM_MIDI_IN || USE_PLATFORM_MIDI_OUT
