src/java.desktop/linux/native/libjsound/PLATFORM_API_LinuxOS_ALSA_MidiOut.c
author neliasso
Mon, 01 Jul 2019 10:49:58 +0200
changeset 55536 8313c42345d5
parent 49289 148e29df1644
permissions -rw-r--r--
8226287: Make process_users_of_allocation handle gc barriers Reviewed-by: kvn, roland
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) 2003, 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
#if USE_PLATFORM_MIDI_OUT == TRUE
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
#include <alsa/asoundlib.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
#include "PlatformMidi.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
#include "PLATFORM_API_LinuxOS_ALSA_MidiUtils.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
static int CHANNEL_MESSAGE_LENGTH[] = {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
    -1, -1, -1, -1, -1, -1, -1, -1, 3, 3, 3, 3, 2, 2, 3 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
/*                                 8x 9x Ax Bx Cx Dx Ex */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
static int SYSTEM_MESSAGE_LENGTH[] = {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
    -1, 2, 3, 2, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
/*  F0 F1 F2 F3  F4  F5 F6 F7 F8  F9 FA FB FC  FD FE FF */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
// the returned length includes the status byte.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
// for illegal messages, -1 is returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
static int getShortMessageLength(int status) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
        int     dataLength = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
        if (status < 0xF0) { // channel voice message
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
                dataLength = CHANNEL_MESSAGE_LENGTH[(status >> 4) & 0xF];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
                dataLength = SYSTEM_MESSAGE_LENGTH[status & 0xF];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
        return dataLength;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 * implementation of the platform-dependent
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 * MIDI out functions declared in PlatformMidi.h
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
char* MIDI_OUT_GetErrorStr(INT32 err) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
    return (char*) getErrorStr(err);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
INT32 MIDI_OUT_GetNumDevices() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
    TRACE0("MIDI_OUT_GetNumDevices()\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
    return getMidiDeviceCount(SND_RAWMIDI_STREAM_OUTPUT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
INT32 MIDI_OUT_GetDeviceName(INT32 deviceIndex, char *name, UINT32 nameLength) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
    TRACE0("MIDI_OUT_GetDeviceName()\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    return getMidiDeviceName(SND_RAWMIDI_STREAM_OUTPUT, deviceIndex,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
                             name, nameLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
INT32 MIDI_OUT_GetDeviceVendor(INT32 deviceIndex, char *name, UINT32 nameLength) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    TRACE0("MIDI_OUT_GetDeviceVendor()\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
    return getMidiDeviceVendor(deviceIndex, name, nameLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
INT32 MIDI_OUT_GetDeviceDescription(INT32 deviceIndex, char *name, UINT32 nameLength) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    TRACE0("MIDI_OUT_GetDeviceDescription()\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    return getMidiDeviceDescription(SND_RAWMIDI_STREAM_OUTPUT, deviceIndex,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
                                    name, nameLength);
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_GetDeviceVersion(INT32 deviceIndex, char *name, UINT32 nameLength) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
    TRACE0("MIDI_OUT_GetDeviceVersion()\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    return getMidiDeviceVersion(deviceIndex, name, nameLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
/* *************************** MidiOutDevice implementation *************** */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
INT32 MIDI_OUT_OpenDevice(INT32 deviceIndex, MidiDeviceHandle** handle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
    TRACE1("MIDI_OUT_OpenDevice(): deviceIndex: %d\n", (int) deviceIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
    return openMidiDevice(SND_RAWMIDI_STREAM_OUTPUT, deviceIndex, handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
INT32 MIDI_OUT_CloseDevice(MidiDeviceHandle* handle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    TRACE0("MIDI_OUT_CloseDevice()\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
    return closeMidiDevice(handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
INT64 MIDI_OUT_GetTimeStamp(MidiDeviceHandle* handle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    return getMidiTimestamp(handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
INT32 MIDI_OUT_SendShortMessage(MidiDeviceHandle* handle, UINT32 packedMsg,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
                                UINT32 timestamp) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    int err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
    int status;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
    int data1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
    int data2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
    char buffer[3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    TRACE2("> MIDI_OUT_SendShortMessage() %x, time: %u\n", packedMsg, (unsigned int) timestamp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    if (!handle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
        ERROR0("< ERROR: MIDI_OUT_SendShortMessage(): handle is NULL\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
        return MIDI_INVALID_HANDLE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    if (!handle->deviceHandle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): native handle is NULL\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
        return MIDI_INVALID_HANDLE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
    status = (packedMsg & 0xFF);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    buffer[0] = (char) status;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
    buffer[1]  = (char) ((packedMsg >> 8) & 0xFF);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    buffer[2]  = (char) ((packedMsg >> 16) & 0xFF);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
    TRACE4("status: %d, data1: %d, data2: %d, length: %d\n", (int) buffer[0], (int) buffer[1], (int) buffer[2], getShortMessageLength(status));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    err = snd_rawmidi_write((snd_rawmidi_t*) handle->deviceHandle, buffer, getShortMessageLength(status));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    if (err < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
        ERROR1("  ERROR: MIDI_OUT_SendShortMessage(): snd_rawmidi_write() returned %d\n", err);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
    TRACE0("< MIDI_OUT_SendShortMessage()\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
    return err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
INT32 MIDI_OUT_SendLongMessage(MidiDeviceHandle* handle, UBYTE* data,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
                               UINT32 size, UINT32 timestamp) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    int err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
    TRACE2("> MIDI_OUT_SendLongMessage() size %u, time: %u\n", (unsigned int) size, (unsigned int) timestamp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
    if (!handle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): handle is NULL\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
        return MIDI_INVALID_HANDLE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
    if (!handle->deviceHandle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): native handle is NULL\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        return MIDI_INVALID_HANDLE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
    if (!data) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
        ERROR0("< ERROR: MIDI_OUT_SendLongMessage(): data is NULL\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
        return MIDI_INVALID_HANDLE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
    err = snd_rawmidi_write((snd_rawmidi_t*) handle->deviceHandle,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
                            data, size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
    if (err < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
        ERROR1("  ERROR: MIDI_OUT_SendLongMessage(): snd_rawmidi_write() returned %d\n", err);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
    TRACE0("< MIDI_OUT_SendLongMessage()\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
    return err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
#endif /* USE_PLATFORM_MIDI_OUT */