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