jdk/src/windows/native/com/sun/media/sound/PLATFORM_API_WinOS_MidiIn.cpp
author ohair
Tue, 11 Sep 2012 13:40:59 -0700
changeset 13678 5c8001201f98
parent 5506 202f599c92aa
child 23010 6dadb192ad81
permissions -rw-r--r--
7197771: Adjust jdk sources to avoid use of implementation defined value of __FILE__ 7180608: Sort the order of object files when building shared libraries Reviewed-by: ohrstrom, erikj, tbell
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     2
 * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
#define USE_ERROR
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
#define USE_TRACE
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
/* include Java Sound specific headers as C code */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
extern "C" {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
#include "PLATFORM_API_WinOS_Util.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
#if USE_PLATFORM_MIDI_IN == TRUE
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
#ifdef USE_ERROR
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
#include <stdio.h>
13678
5c8001201f98 7197771: Adjust jdk sources to avoid use of implementation defined value of __FILE__
ohair
parents: 5506
diff changeset
    38
5c8001201f98 7197771: Adjust jdk sources to avoid use of implementation defined value of __FILE__
ohair
parents: 5506
diff changeset
    39
/* Use THIS_FILE when it is available. */
5c8001201f98 7197771: Adjust jdk sources to avoid use of implementation defined value of __FILE__
ohair
parents: 5506
diff changeset
    40
#ifndef THIS_FILE
5c8001201f98 7197771: Adjust jdk sources to avoid use of implementation defined value of __FILE__
ohair
parents: 5506
diff changeset
    41
    #define THIS_FILE __FILE__
5c8001201f98 7197771: Adjust jdk sources to avoid use of implementation defined value of __FILE__
ohair
parents: 5506
diff changeset
    42
#endif
5c8001201f98 7197771: Adjust jdk sources to avoid use of implementation defined value of __FILE__
ohair
parents: 5506
diff changeset
    43
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
#define MIDIIN_CHECK_ERROR { \
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
        if (err != MMSYSERR_NOERROR) \
13678
5c8001201f98 7197771: Adjust jdk sources to avoid use of implementation defined value of __FILE__
ohair
parents: 5506
diff changeset
    46
            ERROR3("MIDI IN Error in %s:%d : %s\n", THIS_FILE, __LINE__, MIDI_IN_GetErrorStr((INT32) err)); \
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
#else
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
#define MIDIIN_CHECK_ERROR
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * Callback from the MIDI device for all messages.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
//$$fb dwParam1 holds a pointer for long messages. How can that be a DWORD then ???
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
void CALLBACK MIDI_IN_PutMessage( HMIDIIN hMidiIn, UINT wMsg, UINT_PTR dwInstance, UINT_PTR dwParam1, UINT_PTR dwParam2 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
    MidiDeviceHandle* handle = (MidiDeviceHandle*) dwInstance;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
    TRACE3("> MIDI_IN_PutMessage, hMidiIn: %x, wMsg: %x, dwInstance: %x\n", hMidiIn, wMsg, dwInstance);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
    TRACE2("                      dwParam1: %x, dwParam2: %x\n", dwParam1, dwParam2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
    switch(wMsg) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
    case MIM_OPEN:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
        TRACE0("< MIDI_IN_PutMessage: MIM_OPEN\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
    case MIM_CLOSE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
        TRACE0("< MIDI_IN_PutMessage: MIM_CLOSE\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
    case MIM_MOREDATA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    case MIM_DATA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
        TRACE3("  MIDI_IN_PutMessage: MIM_MOREDATA or MIM_DATA. status=%x  data1=%x  data2=%x\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
               dwParam1 & 0xFF, (dwParam1 & 0xFF00)>>8, (dwParam1 & 0xFF0000)>>16);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
        if (handle!=NULL && handle->queue!=NULL && handle->platformData) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
            MIDI_QueueAddShort(handle->queue,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
                               // queue stores packedMsg in big endian
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
                               //(dwParam1 << 24) | ((dwParam1 << 8) & 0xFF0000) | ((dwParam1 >> 8) & 0xFF00),
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
                               (UINT32) dwParam1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
                               // queue uses microseconds
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
                               ((INT64) dwParam2)*1000,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
                               // overwrite if queue is full
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
                               TRUE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
            SetEvent((HANDLE) handle->platformData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
        TRACE0("< MIDI_IN_PutMessage\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    case MIM_LONGDATA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
        TRACE1("  MIDI_IN_PutMessage: MIM_LONGDATA (%d bytes recorded)\n", (int) (((MIDIHDR*) dwParam1)->dwBytesRecorded));
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
        if (handle!=NULL && handle->queue!=NULL && handle->platformData) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
            MIDIHDR* hdr = (MIDIHDR*) dwParam1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
            TRACE2("  MIDI_IN_PutMessage: Adding to queue: index %d, %d bytes\n", (INT32) hdr->dwUser, hdr->dwBytesRecorded);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
            MIDI_QueueAddLong(handle->queue,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
                              (UBYTE*) hdr->lpData,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
                              (UINT32) hdr->dwBytesRecorded,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
                              // sysex buffer index
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
                              (INT32) hdr->dwUser,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
                              // queue uses microseconds
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
                              ((INT64) dwParam2)*1000,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
                              // overwrite if queue is full
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
                              TRUE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
            SetEvent((HANDLE) handle->platformData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
        TRACE0("< MIDI_IN_PutMessage\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
    case MIM_ERROR:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
        ERROR0("< MIDI_IN_PutMessage: MIM_ERROR!\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    case MIM_LONGERROR:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
        if (dwParam1 != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
            MIDIHDR* hdr = (MIDIHDR*) dwParam1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
#ifdef USE_TRACE
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
            if (hdr->dwBytesRecorded > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
                TRACE2("  MIDI_IN_PutMessage: MIM_LONGERROR! recorded: %d bytes with status 0x%2x\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
                        hdr->dwBytesRecorded, (int) (*((UBYTE*) hdr->lpData)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
            // re-add hdr to device query
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
            hdr->dwBytesRecorded = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
            midiInAddBuffer((HMIDIIN)handle->deviceHandle, hdr, sizeof(MIDIHDR));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
        ERROR0("< MIDI_IN_PutMessage: MIM_LONGERROR!\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
    default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
        ERROR1("< MIDI_IN_PutMessage: ERROR unknown message %d!\n", wMsg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
    } // switch (wMsg)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
** data/routines for opening MIDI input (MidiIn) device by separate thread
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
** (joint into MidiIn_OpenHelper class)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
** see 6415669 - MidiIn device stops work and crushes JVM after exiting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
** from thread that has open the device (it looks like WinMM bug).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
*/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
class MidiIn_OpenHelper {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
public:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
    /* opens MidiIn device  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
    static MMRESULT midiInOpen(INT32 deviceID, MidiDeviceHandle* handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
    /* checks for initialization success */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
    static inline BOOL isInitialized() { return data.threadHandle != NULL; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
protected:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    MidiIn_OpenHelper() {}  // no need to create an instance
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    /* data class */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    class Data {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
    public:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
        Data();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
        ~Data();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
        // public data to access from parent class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
        CRITICAL_SECTION crit_sect;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
        volatile HANDLE threadHandle;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
        volatile HANDLE doEvent;    // event to resume thread
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        volatile HANDLE doneEvent;  // processing has been completed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
        volatile MMRESULT err;      // processing result
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
        // data to process; (handle == null) is command to thread terminating
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
        volatile INT32 deviceID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
        volatile MidiDeviceHandle* handle;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
    } static data;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
    /* StartThread function */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
    static DWORD WINAPI __stdcall ThreadProc(void *param);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
};
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
/* MidiIn_OpenHelper class implementation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
*/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
MidiIn_OpenHelper::Data MidiIn_OpenHelper::data;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
MidiIn_OpenHelper::Data::Data() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
    threadHandle = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
    ::InitializeCriticalSection(&crit_sect);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
    doEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
    doneEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
    if (doEvent != NULL && doneEvent != NULL)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
        threadHandle = ::CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
MidiIn_OpenHelper::Data::~Data() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
    ::EnterCriticalSection(&crit_sect);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
    if (threadHandle != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
        // terminate thread
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
        handle = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
        ::SetEvent(doEvent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
        ::CloseHandle(threadHandle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
        threadHandle = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
    ::LeaveCriticalSection(&crit_sect);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
    // won't delete doEvent/doneEvent/crit_sect
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
    // - Windows will do during process shutdown
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
DWORD WINAPI __stdcall MidiIn_OpenHelper::ThreadProc(void *param) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
    while (1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
        // wait for something to do
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
        ::WaitForSingleObject(data.doEvent, INFINITE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
        if (data.handle == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
            // (data.handle == NULL) is a signal to terminate thread
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
        data.err = ::midiInOpen((HMIDIIN*)&(data.handle->deviceHandle),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
                                data.deviceID, (UINT_PTR)&(MIDI_IN_PutMessage),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
                                (UINT_PTR)data.handle,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
                                CALLBACK_FUNCTION|MIDI_IO_STATUS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
        ::SetEvent(data.doneEvent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
    return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
MMRESULT MidiIn_OpenHelper::midiInOpen(INT32 deviceID, MidiDeviceHandle* handle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
    MMRESULT err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
    ::EnterCriticalSection(&data.crit_sect);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
    if (!isInitialized()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
        ::LeaveCriticalSection(&data.crit_sect);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
        return MMSYSERR_ERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
    data.deviceID = deviceID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
    data.handle = handle;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
    ::SetEvent(data.doEvent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
    ::WaitForSingleObject(data.doneEvent, INFINITE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
    err = data.err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
    ::LeaveCriticalSection(&data.crit_sect);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
    return err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
// PLATFORM_MIDI_IN method implementations
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
/* not thread safe */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
static char winMidiInErrMsg[WIN_MAX_ERROR_LEN];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
char* MIDI_IN_GetErrorStr(INT32 err) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
    winMidiInErrMsg[0] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
    midiInGetErrorText((MMRESULT) err, winMidiInErrMsg, WIN_MAX_ERROR_LEN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
    return winMidiInErrMsg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
INT32 MIDI_IN_GetNumDevices() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
    return (INT32) midiInGetNumDevs();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
INT32 getMidiInCaps(INT32 deviceID, MIDIINCAPS* caps, INT32* err) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
    (*err) = midiInGetDevCaps(deviceID, caps, sizeof(MIDIINCAPS));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
    return ((*err) == MMSYSERR_NOERROR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
INT32 MIDI_IN_GetDeviceName(INT32 deviceID, char *name, UINT32 nameLength) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
    MIDIINCAPS midiInCaps;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
    INT32 err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
    if (getMidiInCaps(deviceID, &midiInCaps, &err)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
        strncpy(name, midiInCaps.szPname, nameLength-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
        name[nameLength-1] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
        return MIDI_SUCCESS;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
    MIDIIN_CHECK_ERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
    return err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
INT32 MIDI_IN_GetDeviceVendor(INT32 deviceID, char *name, UINT32 nameLength) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
    return MIDI_NOT_SUPPORTED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
INT32 MIDI_IN_GetDeviceDescription(INT32 deviceID, char *name, UINT32 nameLength) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
    return MIDI_NOT_SUPPORTED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
INT32 MIDI_IN_GetDeviceVersion(INT32 deviceID, char *name, UINT32 nameLength) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
    MIDIINCAPS midiInCaps;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
    INT32 err = MIDI_NOT_SUPPORTED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
    if (getMidiInCaps(deviceID, &midiInCaps, &err) && (nameLength>7)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        sprintf(name, "%d.%d", (midiInCaps.vDriverVersion & 0xFF00) >> 8, midiInCaps.vDriverVersion & 0xFF);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        return MIDI_SUCCESS;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
    MIDIIN_CHECK_ERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
    return err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
INT32 prepareBuffers(MidiDeviceHandle* handle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
    SysExQueue* sysex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
    MMRESULT err = MMSYSERR_NOERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
    int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
    if (!handle || !handle->longBuffers || !handle->deviceHandle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
        ERROR0("MIDI_IN_prepareBuffers: handle, or longBuffers, or deviceHandle==NULL\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
        return MIDI_INVALID_HANDLE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
    sysex = (SysExQueue*) handle->longBuffers;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
    for (i = 0; i<sysex->count; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
        MIDIHDR* hdr = &(sysex->header[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
        midiInPrepareHeader((HMIDIIN) handle->deviceHandle, hdr, sizeof(MIDIHDR));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
        err = midiInAddBuffer((HMIDIIN) handle->deviceHandle, hdr, sizeof(MIDIHDR));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
    MIDIIN_CHECK_ERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
    return (INT32) err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
INT32 unprepareBuffers(MidiDeviceHandle* handle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
    SysExQueue* sysex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
    MMRESULT err = MMSYSERR_NOERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
    int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
    if (!handle || !handle->longBuffers || !handle->deviceHandle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
        ERROR0("MIDI_IN_unprepareBuffers: handle, or longBuffers, or deviceHandle==NULL\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
        return MIDI_INVALID_HANDLE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
    sysex = (SysExQueue*) handle->longBuffers;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
    for (i = 0; i<sysex->count; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
        err = midiInUnprepareHeader((HMIDIIN) handle->deviceHandle, &(sysex->header[i]), sizeof(MIDIHDR));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
    MIDIIN_CHECK_ERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
    return (INT32) err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
INT32 MIDI_IN_OpenDevice(INT32 deviceID, MidiDeviceHandle** handle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
    MMRESULT err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
    TRACE0("> MIDI_IN_OpenDevice\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
#ifdef USE_ERROR
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
    setvbuf(stdout, NULL, (int)_IONBF, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
    setvbuf(stderr, NULL, (int)_IONBF, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
    (*handle) = (MidiDeviceHandle*) malloc(sizeof(MidiDeviceHandle));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
    if (!(*handle)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
        ERROR0("< ERROR: MIDI_IN_OpenDevice: out of memory\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
        return MIDI_OUT_OF_MEMORY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
    memset(*handle, 0, sizeof(MidiDeviceHandle));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
    // create queue
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
    (*handle)->queue = MIDI_CreateQueue(MIDI_IN_MESSAGE_QUEUE_SIZE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
    if (!(*handle)->queue) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
        ERROR0("< ERROR: MIDI_IN_OpenDevice: could not create queue\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
        free(*handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
        (*handle) = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
        return MIDI_OUT_OF_MEMORY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
    // create long buffer queue
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
    if (!MIDI_WinCreateLongBufferQueue(*handle, MIDI_IN_LONG_QUEUE_SIZE, MIDI_IN_LONG_MESSAGE_SIZE, NULL)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
        ERROR0("< ERROR: MIDI_IN_OpenDevice: could not create long Buffers\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
        MIDI_DestroyQueue((*handle)->queue);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
        free(*handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
        (*handle) = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
        return MIDI_OUT_OF_MEMORY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
    // finally open the device
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
    err = MidiIn_OpenHelper::midiInOpen(deviceID, *handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
    if ((err != MMSYSERR_NOERROR) || (!(*handle)->deviceHandle)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
        MIDIIN_CHECK_ERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
        MIDI_WinDestroyLongBufferQueue(*handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
        MIDI_DestroyQueue((*handle)->queue);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
        free(*handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
        (*handle) = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
        return (INT32) err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
    prepareBuffers(*handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
        MIDI_SetStartTime(*handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
    TRACE0("< MIDI_IN_OpenDevice: midiInOpen succeeded\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
    return MIDI_SUCCESS;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
INT32 MIDI_IN_CloseDevice(MidiDeviceHandle* handle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
    MMRESULT err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
    TRACE0("> MIDI_IN_CloseDevice: midiInClose\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
    if (!handle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
        ERROR0("ERROR: MIDI_IN_CloseDevice: handle is NULL\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
        return MIDI_INVALID_HANDLE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
    midiInReset((HMIDIIN) handle->deviceHandle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
    unprepareBuffers(handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
    err = midiInClose((HMIDIIN) handle->deviceHandle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
    handle->deviceHandle=NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
    MIDIIN_CHECK_ERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
    MIDI_WinDestroyLongBufferQueue(handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
    if (handle->queue!=NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
        MidiMessageQueue* queue = handle->queue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
        handle->queue = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
        MIDI_DestroyQueue(queue);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
    free(handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
    TRACE0("< MIDI_IN_CloseDevice: midiInClose succeeded\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
    return (INT32) err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
INT32 MIDI_IN_StartDevice(MidiDeviceHandle* handle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
    MMRESULT err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
    if (!handle || !handle->deviceHandle || !handle->queue) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
        ERROR0("ERROR: MIDI_IN_StartDevice: handle or queue is NULL\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
        return MIDI_INVALID_HANDLE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
    // clear all the events from the queue
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
    MIDI_QueueClear(handle->queue);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
    handle->platformData = (void*) CreateEvent(NULL, FALSE /*manual reset*/, FALSE /*signaled*/, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
    if (!handle->platformData) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
        ERROR0("ERROR: MIDI_IN_StartDevice: could not create event\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
        return MIDI_OUT_OF_MEMORY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
    err = midiInStart((HMIDIIN) handle->deviceHandle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
        /* $$mp 200308-11: This method is already called in ...open(). It is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
           unclear why is is called again. The specification says that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
           MidiDevice.getMicrosecondPosition() returns the time since the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
           device was opened (the spec doesn't know about start/stop).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
           So I guess this call is obsolete. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
        MIDI_SetStartTime(handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
    MIDIIN_CHECK_ERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
    TRACE0("MIDI_IN_StartDevice: midiInStart finished\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
    return (INT32) err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
INT32 MIDI_IN_StopDevice(MidiDeviceHandle* handle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
    MMRESULT err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
    HANDLE event;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
    TRACE0("> MIDI_IN_StopDevice: midiInStop \n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
    if (!handle || !handle->platformData) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
        ERROR0("ERROR: MIDI_IN_StopDevice: handle or event is NULL\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
        return MIDI_INVALID_HANDLE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
    // encourage MIDI_IN_GetMessage to return soon
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
    event = handle->platformData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
    handle->platformData = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
    SetEvent(event);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
    err = midiInStop((HMIDIIN) handle->deviceHandle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
    // wait until the Java thread has exited
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
    while (handle->isWaiting) Sleep(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
    CloseHandle(event);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
    MIDIIN_CHECK_ERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
    TRACE0("< MIDI_IN_StopDevice: midiInStop finished\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
    return (INT32) err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
/* return time stamp in microseconds */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
INT64 MIDI_IN_GetTimeStamp(MidiDeviceHandle* handle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
        return MIDI_GetTimeStamp(handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
// read the next message from the queue
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
MidiMessage* MIDI_IN_GetMessage(MidiDeviceHandle* handle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
    if (handle == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
        return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
    while (handle->queue!=NULL && handle->platformData!=NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
        MidiMessage* msg = MIDI_QueueRead(handle->queue);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
        DWORD res;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
        if (msg != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
            //fprintf(stdout, "GetMessage returns index %d\n", msg->data.l.index); fflush(stdout);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
            return msg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
        TRACE0("MIDI_IN_GetMessage: before waiting\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
        handle->isWaiting = TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
        res = WaitForSingleObject((HANDLE) handle->platformData, 2000);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
        handle->isWaiting = FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
        if (res == WAIT_TIMEOUT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
            // break out back to Java from time to time - just to be sure
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
            TRACE0("MIDI_IN_GetMessage: waiting finished with timeout\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
        TRACE0("MIDI_IN_GetMessage: waiting finished\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
    return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
void MIDI_IN_ReleaseMessage(MidiDeviceHandle* handle, MidiMessage* msg) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
    SysExQueue* sysex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
    if (handle == NULL || handle->queue == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
    sysex = (SysExQueue*) handle->longBuffers;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
    if (msg->type == LONG_MESSAGE && sysex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
        MIDIHDR* hdr = &(sysex->header[msg->data.l.index]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
        //fprintf(stdout, "ReleaseMessage index %d\n", msg->data.l.index); fflush(stdout);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
        hdr->dwBytesRecorded = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
        midiInAddBuffer((HMIDIIN) handle->deviceHandle, hdr, sizeof(MIDIHDR));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
    MIDI_QueueRemove(handle->queue, TRUE /*onlyLocked*/);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
#endif // USE_PLATFORM_MIDI_IN