jdk/src/windows/native/com/sun/media/sound/PLATFORM_API_WinOS_MidiOut.c
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 "PLATFORM_API_WinOS_Util.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
#if USE_PLATFORM_MIDI_OUT == TRUE
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
#ifdef USE_ERROR
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
#include <stdio.h>
13678
5c8001201f98 7197771: Adjust jdk sources to avoid use of implementation defined value of __FILE__
ohair
parents: 5506
diff changeset
    36
5c8001201f98 7197771: Adjust jdk sources to avoid use of implementation defined value of __FILE__
ohair
parents: 5506
diff changeset
    37
/* 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
    38
#ifndef THIS_FILE
5c8001201f98 7197771: Adjust jdk sources to avoid use of implementation defined value of __FILE__
ohair
parents: 5506
diff changeset
    39
    #define THIS_FILE __FILE__
5c8001201f98 7197771: Adjust jdk sources to avoid use of implementation defined value of __FILE__
ohair
parents: 5506
diff changeset
    40
#endif
5c8001201f98 7197771: Adjust jdk sources to avoid use of implementation defined value of __FILE__
ohair
parents: 5506
diff changeset
    41
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
#define MIDIOUT_CHECK_ERROR  { \
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
        if (err != MMSYSERR_NOERROR) \
13678
5c8001201f98 7197771: Adjust jdk sources to avoid use of implementation defined value of __FILE__
ohair
parents: 5506
diff changeset
    44
            ERROR3("MIDI OUT Error in %s:%d : %s\n", THIS_FILE, __LINE__, MIDI_OUT_GetErrorStr((INT32) err)); \
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
#else
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
#define MIDIOUT_CHECK_ERROR
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
/* *************************** MidiOutDeviceProvider implementation *********************************** */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
/* not thread safe */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
static char winMidiOutErrMsg[WIN_MAX_ERROR_LEN];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
char* MIDI_OUT_GetErrorStr(INT32 err) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
    winMidiOutErrMsg[0] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
    midiOutGetErrorText((MMRESULT) err, winMidiOutErrMsg, WIN_MAX_ERROR_LEN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
    return winMidiOutErrMsg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
INT32 MIDI_OUT_GetNumDevices() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
    // add one for the MIDI_MAPPER
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
    // we want to return it first so it'll be the default, so we
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
    // decrement each deviceID for these methods....
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
    return (INT32) (midiOutGetNumDevs() + 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
INT32 getMidiOutCaps(INT32 deviceID, MIDIOUTCAPS* caps, INT32* err) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
    if (deviceID == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
        deviceID = MIDI_MAPPER;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
        deviceID--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
    (*err) = (INT32) midiOutGetDevCaps(deviceID, caps, sizeof(MIDIOUTCAPS));
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    return ((*err) == MMSYSERR_NOERROR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
INT32 MIDI_OUT_GetDeviceName(INT32 deviceID, char *name, UINT32 nameLength) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    MIDIOUTCAPS midiOutCaps;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    INT32 err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    if (getMidiOutCaps(deviceID, &midiOutCaps, &err)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
        strncpy(name, midiOutCaps.szPname, nameLength-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
        name[nameLength-1] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
        return MIDI_SUCCESS;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    MIDIOUT_CHECK_ERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    return err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
INT32 MIDI_OUT_GetDeviceVendor(INT32 deviceID, char *name, UINT32 nameLength) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
    return MIDI_NOT_SUPPORTED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
INT32 MIDI_OUT_GetDeviceDescription(INT32 deviceID, char *name, UINT32 nameLength) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
    MIDIOUTCAPS midiOutCaps;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
    char *desc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    INT32 err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
    if (getMidiOutCaps(deviceID, &midiOutCaps, &err)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
        int tech = (int)midiOutCaps.wTechnology;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
        switch(tech) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
        case MOD_MIDIPORT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
            desc = "External MIDI Port";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
        case MOD_SQSYNTH:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
            desc = "Internal square wave synthesizer";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
        case MOD_FMSYNTH:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
            desc = "Internal FM synthesizer";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
        case MOD_SYNTH:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
            desc = "Internal synthesizer (generic)";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
        case MOD_MAPPER:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
            desc = "Windows MIDI_MAPPER";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
        case 7 /* MOD_SWSYNTH*/:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
            desc = "Internal software synthesizer";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
            return MIDI_NOT_SUPPORTED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
        strncpy(name, desc, nameLength-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
        name[nameLength-1] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
        return MIDI_SUCCESS;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    return err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
INT32 MIDI_OUT_GetDeviceVersion(INT32 deviceID, char *name, UINT32 nameLength) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    MIDIOUTCAPS midiOutCaps;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
    INT32 err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
    if (getMidiOutCaps(deviceID, &midiOutCaps, &err) && nameLength>7) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
        sprintf(name, "%d.%d", (midiOutCaps.vDriverVersion & 0xFF00) >> 8, midiOutCaps.vDriverVersion & 0xFF);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
        return MIDI_SUCCESS;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    MIDIOUT_CHECK_ERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
    return err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
/* *************************** MidiOutDevice implementation ***************************************** */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
INT32 unprepareLongBuffers(MidiDeviceHandle* handle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    SysExQueue* sysex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    MMRESULT err = MMSYSERR_NOERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
    int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
    if (!handle || !handle->deviceHandle || !handle->longBuffers) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
        ERROR0("MIDI_OUT_unprepareLongBuffers: handle, deviceHandle, or longBuffers == NULL\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
        return MIDI_INVALID_HANDLE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
    sysex = (SysExQueue*) handle->longBuffers;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
    for (i = 0; i<sysex->count; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
        MIDIHDR* hdr = &(sysex->header[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
        if (hdr->dwFlags) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
            err = midiOutUnprepareHeader((HMIDIOUT) handle->deviceHandle, hdr, sizeof(MIDIHDR));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
    MIDIOUT_CHECK_ERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
    return (INT32) err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
INT32 freeLongBuffer(MIDIHDR* hdr, HMIDIOUT deviceHandle, INT32 minToLeaveData) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
    MMRESULT err = MMSYSERR_NOERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
    if (!hdr) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        ERROR0("MIDI_OUT_freeLongBuffer: hdr == NULL\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        return MIDI_INVALID_HANDLE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
    if (hdr->dwFlags && deviceHandle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
        err = midiOutUnprepareHeader(deviceHandle, hdr, sizeof(MIDIHDR));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
    if (hdr->lpData && (((INT32) hdr->dwBufferLength) < minToLeaveData || minToLeaveData < 0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
        free(hdr->lpData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
        hdr->lpData=NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
        hdr->dwBufferLength=0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
    hdr->dwBytesRecorded=0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
    hdr->dwFlags=0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
    return (INT32) err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
INT32 freeLongBuffers(MidiDeviceHandle* handle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
    SysExQueue* sysex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
    MMRESULT err = MMSYSERR_NOERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
    int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
    if (!handle || !handle->longBuffers) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
        ERROR0("MIDI_OUT_freeLongBuffers: handle or longBuffers == NULL\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
        return MIDI_INVALID_HANDLE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
    sysex = (SysExQueue*) handle->longBuffers;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
    for (i = 0; i<sysex->count; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
        err = freeLongBuffer(&(sysex->header[i]), (HMIDIOUT) handle->deviceHandle, -1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
    MIDIOUT_CHECK_ERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
    return (INT32) err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
INT32 MIDI_OUT_OpenDevice(INT32 deviceID, MidiDeviceHandle** handle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
    MMRESULT err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
    TRACE1(">> MIDI_OUT_OpenDevice: deviceID: %d\n", deviceID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
    if (deviceID == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
        deviceID = MIDI_MAPPER;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
        deviceID--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
#ifdef USE_ERROR
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
    setvbuf(stdout, NULL, (int)_IONBF, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
    setvbuf(stderr, NULL, (int)_IONBF, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
    (*handle) = (MidiDeviceHandle*) malloc(sizeof(MidiDeviceHandle));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
    if (!(*handle)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
        ERROR0("ERROR: MIDI_OUT_OpenDevice: out of memory\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
        return MIDI_OUT_OF_MEMORY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
    memset(*handle, 0, sizeof(MidiDeviceHandle));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
    // create long buffer queue
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
    if (!MIDI_WinCreateEmptyLongBufferQueue(*handle, MIDI_OUT_LONG_QUEUE_SIZE)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
        ERROR0("ERROR: MIDI_OUT_OpenDevice: could not create long Buffers\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        free(*handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
        (*handle) = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
        return MIDI_OUT_OF_MEMORY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
    // create notification event
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
    (*handle)->platformData = (void*) CreateEvent(NULL, FALSE /*manual reset*/, FALSE /*signaled*/, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
    if (!(*handle)->platformData) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
        ERROR0("ERROR: MIDI_OUT_StartDevice: could not create event\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        MIDI_WinDestroyLongBufferQueue(*handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
        free(*handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
        (*handle) = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
        return MIDI_OUT_OF_MEMORY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
    // finally open the device
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
    err = midiOutOpen((HMIDIOUT*) &((*handle)->deviceHandle), deviceID,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
                      (UINT_PTR) (*handle)->platformData, (UINT_PTR) (*handle), CALLBACK_EVENT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
    if ((err != MMSYSERR_NOERROR) || (!(*handle)->deviceHandle)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
        /* some devices return non zero, but no error! */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
        if (midiOutShortMsg((HMIDIOUT) ((*handle)->deviceHandle),0) == MMSYSERR_INVALHANDLE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
            MIDIOUT_CHECK_ERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
            CloseHandle((HANDLE) (*handle)->platformData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
            MIDI_WinDestroyLongBufferQueue(*handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
            free(*handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
            (*handle) = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
            return (INT32) err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
    //$$fb enable high resolution time
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
    timeBeginPeriod(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
    MIDI_SetStartTime(*handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
    TRACE0("<< MIDI_OUT_OpenDevice: succeeded\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
    return MIDI_SUCCESS;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
INT32 MIDI_OUT_CloseDevice(MidiDeviceHandle* handle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
    MMRESULT err = MMSYSERR_NOERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
    HANDLE event;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
    TRACE0("> MIDI_OUT_CloseDevice\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
    if (!handle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
        ERROR0("ERROR: MIDI_OUT_StopDevice: handle is NULL\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
        return MIDI_INVALID_HANDLE; // failure
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
    // encourage MIDI_OUT_SendLongMessage to return soon
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
    event = handle->platformData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
    handle->platformData = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
    if (event) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
        SetEvent(event);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        ERROR0("ERROR: MIDI_OUT_StopDevice: event is NULL\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
    if (handle->deviceHandle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
        //$$fb disable high resolution time
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
        timeEndPeriod(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
        err = midiOutReset((HMIDIOUT) handle->deviceHandle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
        ERROR0("ERROR: MIDI_OUT_CloseDevice: deviceHandle is NULL\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
    // issue a "SUSTAIN OFF" message to each MIDI channel, 0 to 15.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
    // "CONTROL CHANGE" is 176, "SUSTAIN CONTROLLER" is 64, and the value is 0.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
    // $$fb 2002-04-04: It is responsability of the application developer to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
    // leave the device in a consistent state. So I put this in comments
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
      for (channel = 0; channel < 16; channel++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
      MIDI_OUT_SendShortMessage(deviceHandle, (unsigned char)(176 + channel), (unsigned char)64, (unsigned char)0, (UINT32)-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
    */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
    if (event) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
        // wait until MIDI_OUT_SendLongMessage has finished
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
        while (handle->isWaiting) Sleep(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
    unprepareLongBuffers(handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
    if (handle->deviceHandle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
        err = midiOutClose((HMIDIOUT) handle->deviceHandle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
        MIDIOUT_CHECK_ERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
        handle->deviceHandle = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
    freeLongBuffers(handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
    if (event) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
        CloseHandle(event);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
    MIDI_WinDestroyLongBufferQueue(handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
    free(handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
    TRACE0("< MIDI_OUT_CloseDevice\n");
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
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
/* return time stamp in microseconds */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
INT64 MIDI_OUT_GetTimeStamp(MidiDeviceHandle* handle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
    return MIDI_GetTimeStamp(handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
INT32 MIDI_OUT_SendShortMessage(MidiDeviceHandle* handle, UINT32 packedMsg, UINT32 timestamp) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
    MMRESULT err = MMSYSERR_NOERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
    TRACE2("> MIDI_OUT_SendShortMessage %x, time: %d\n", packedMsg, timestamp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
    if (!handle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
        ERROR0("ERROR: MIDI_OUT_SendShortMessage: handle is NULL\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
        return MIDI_INVALID_HANDLE; // failure
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
    err = midiOutShortMsg((HMIDIOUT) handle->deviceHandle, packedMsg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
    MIDIOUT_CHECK_ERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
    TRACE0("< MIDI_OUT_SendShortMessage\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
    return (INT32) err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
INT32 MIDI_OUT_SendLongMessage(MidiDeviceHandle* handle, UBYTE* data, UINT32 size, UINT32 timestamp) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
    MMRESULT err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
    SysExQueue* sysex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
    MIDIHDR* hdr = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
    INT32 remainingSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
    int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
    TRACE2("> MIDI_OUT_SendLongMessage size %d, time: %d\n", size, timestamp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
    if (!handle || !data || !handle->longBuffers) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
        ERROR0("< ERROR: MIDI_OUT_SendLongMessage: handle, data, or longBuffers is NULL\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
        return MIDI_INVALID_HANDLE; // failure
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
    if (size == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
        return MIDI_SUCCESS;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
    sysex = (SysExQueue*) handle->longBuffers;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
    remainingSize = size;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
    // send in chunks of 512 bytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
    size = 512;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
    while (remainingSize > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
        if (remainingSize < (INT32) size) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
            size = (UINT32) remainingSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
        while (!hdr && handle->platformData) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
            /* find a non-queued header */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
            for (i = 0; i < sysex->count; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
                hdr = &(sysex->header[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
                if ((hdr->dwFlags & MHDR_DONE) || (hdr->dwFlags == 0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
                hdr = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
            /* wait for a buffer to free up */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
            if (!hdr && handle->platformData) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
                DWORD res;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
                TRACE0(" Need to wait for free buffer\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
                handle->isWaiting = TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
                res = WaitForSingleObject((HANDLE) handle->platformData, 700);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
                handle->isWaiting = FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
                if (res == WAIT_TIMEOUT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
                    // break out back to Java if no buffer freed up after 700 milliseconds
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
                    TRACE0("-> TIMEOUT. Need to go back to Java\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
        if (!hdr) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
            // no free buffer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
            return MIDI_NOT_SUPPORTED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
        TRACE2("-> sending %d bytes with buffer index=%d\n", (int) size, (int) hdr->dwUser);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
        freeLongBuffer(hdr, handle->deviceHandle, (INT32) size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
        if (hdr->lpData == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
            hdr->lpData = malloc(size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
            hdr->dwBufferLength = size;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
        hdr->dwBytesRecorded = size;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
        memcpy(hdr->lpData, data, size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
        err = midiOutPrepareHeader((HMIDIOUT) handle->deviceHandle, hdr, sizeof(MIDIHDR));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
        if (err != MMSYSERR_NOERROR) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
            freeLongBuffer(hdr, handle->deviceHandle, -1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
            MIDIOUT_CHECK_ERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
            return (INT32) err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
        err = midiOutLongMsg((HMIDIOUT) handle->deviceHandle, hdr, sizeof(MIDIHDR));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
        if (err != MMSYSERR_NOERROR) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
            freeLongBuffer(hdr, handle->deviceHandle, -1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
            ERROR0("ERROR: MIDI_OUT_SendLongMessage: midiOutLongMsg returned error:\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
            MIDIOUT_CHECK_ERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
            return (INT32) err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
        remainingSize -= size;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
        data += size;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
    TRACE0("< MIDI_OUT_SendLongMessage success\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
    return MIDI_SUCCESS;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
#endif // USE_PLATFORM_MIDI_OUT