diff options
Diffstat (limited to 'portmidi/pm_java')
| -rw-r--r-- | portmidi/pm_java/CMakeLists.txt | 56 | ||||
| -rw-r--r-- | portmidi/pm_java/README.txt | 62 | ||||
| -rw-r--r-- | portmidi/pm_java/jportmidi/JPortMidi.java | 541 | ||||
| -rw-r--r-- | portmidi/pm_java/jportmidi/JPortMidiApi.java | 117 | ||||
| -rw-r--r-- | portmidi/pm_java/jportmidi/JPortMidiException.java | 12 | ||||
| -rw-r--r-- | portmidi/pm_java/make.bat | 50 | ||||
| -rw-r--r-- | portmidi/pm_java/pmjni/jportmidi_JportMidiApi.h | 293 | ||||
| -rw-r--r-- | portmidi/pm_java/pmjni/pmjni.c | 354 | ||||
| -rw-r--r-- | portmidi/pm_java/pmjni/pmjni.rc | 63 |
9 files changed, 1548 insertions, 0 deletions
diff --git a/portmidi/pm_java/CMakeLists.txt b/portmidi/pm_java/CMakeLists.txt new file mode 100644 index 0000000..55a20f4 --- /dev/null +++ b/portmidi/pm_java/CMakeLists.txt | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | # pm_java/CMakeLists.txt -- builds pmjni | ||
| 2 | |||
| 3 | find_package(Java) | ||
| 4 | message(STATUS "Java_JAVA_EXECUTABLE is " ${Java_JAVA_EXECUTABLE}) | ||
| 5 | |||
| 6 | # Build pmjni | ||
| 7 | # this CMakeLists.txt is only loaded if BUILD_JAVA_NATIVE_INTERFACE | ||
| 8 | # This jni library includes portmidi sources to give just | ||
| 9 | # one library for JPortMidi users to manage rather than two. | ||
| 10 | if(UNIX) | ||
| 11 | include(FindJNI) | ||
| 12 | # message(STATUS "JAVA_JVM_LIB_PATH is " ${JAVA_JVM_LIB_PATH}) | ||
| 13 | # message(STATUS "JAVA_INCLUDE_PATH is " ${JAVA_INCLUDE_PATH}) | ||
| 14 | # note: should use JAVA_JVM_LIB_PATH, but it is not set properly | ||
| 15 | # note: user might need to set JAVA_INCLUDE_PATH manually | ||
| 16 | # | ||
| 17 | # this will probably break on BSD and other Unix systems; the fix | ||
| 18 | # depends on whether FindJNI can find Java or not. If yes, then | ||
| 19 | # we should try to rely on automatically set JAVA_INCLUDE_PATH and | ||
| 20 | # JAVA_INCLUDE_PATH2; if no, then we need to make both JAVA_INCLUDE_PATH | ||
| 21 | # and JAVA_INCLUDE_PATH2 set by user (will need clear documentation | ||
| 22 | # because JAVA_INCLUDE_PATH2 is pretty obscure) | ||
| 23 | set(JAVA_INCLUDE_PATH ${JAVA_INCLUDE_PATH-UNKNOWN} | ||
| 24 | CACHE STRING "where to find Java SDK include directory") | ||
| 25 | # libjvm.so is found relative to JAVA_INCLUDE_PATH: | ||
| 26 | if (HAIKU) | ||
| 27 | set(JAVA_INCLUDE_PATHS ${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH}/haiku) | ||
| 28 | else() | ||
| 29 | set(JAVA_INCLUDE_PATHS ${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH}/linux) | ||
| 30 | endif() | ||
| 31 | elseif(WIN32) | ||
| 32 | include(FindJNI) | ||
| 33 | # note: should use JAVA_JVM_LIB_PATH, but it is not set properly | ||
| 34 | set(JAVAVM_LIB ${JAVA_INCLUDE_PATH}/../lib/jvm.lib) | ||
| 35 | |||
| 36 | set(JAVA_INCLUDE_PATHS ${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH2}) | ||
| 37 | # message(STATUS "JAVA_INCLUDE_PATHS: " ${JAVA_INCLUDE_PATHS}) | ||
| 38 | # message(STATUS "JAVAVM_LIB: " ${JAVAVM_LIB}) | ||
| 39 | endif() | ||
| 40 | |||
| 41 | add_library(pmjni SHARED pmjni/pmjni.c) | ||
| 42 | target_sources(pmjni PRIVATE ${PM_LIB_PUBLIC_SRC} ${PM_LIB_PRIVATE_SRC}) | ||
| 43 | message(STATUS "Java paths ${JAVA_INCLUDE_PATHS}") | ||
| 44 | # message(STATUS "Java pmjni src: pmjni/pmjni.c ${PM_LIB_SHARED_SRC} " | ||
| 45 | # "${PM_LIB_PRIVATE_SRC}") | ||
| 46 | target_include_directories(pmjni PUBLIC ${JAVA_INCLUDE_PATHS}) | ||
| 47 | target_link_libraries(pmjni ${PM_NEEDED_LIBS}) | ||
| 48 | set_target_properties(pmjni PROPERTIES | ||
| 49 | VERSION ${LIBRARY_VERSION} | ||
| 50 | SOVERSION ${LIBRARY_SOVERSION} | ||
| 51 | LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" | ||
| 52 | RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" | ||
| 53 | ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" | ||
| 54 | EXECUTABLE_EXTENSION "jnilib" | ||
| 55 | MACOSX_RPATH ON) | ||
| 56 | |||
diff --git a/portmidi/pm_java/README.txt b/portmidi/pm_java/README.txt new file mode 100644 index 0000000..d1e5ad5 --- /dev/null +++ b/portmidi/pm_java/README.txt | |||
| @@ -0,0 +1,62 @@ | |||
| 1 | README.txt | ||
| 2 | Roger B. Dannenberg | ||
| 3 | 16 Jun 2009 | ||
| 4 | updated 2021 | ||
| 5 | |||
| 6 | This directory implements a JNI library so that Java programs can use | ||
| 7 | the PortMidi API. This was mainly created to implement PmDefaults, a | ||
| 8 | program to set default input and output devices for PortMidi | ||
| 9 | applications. Because it is rarely used, PmDefaults was dropped from | ||
| 10 | PortMidi starting with v3. I recommend you implement per-application | ||
| 11 | preferences and store default PortMidi device numbers for input and | ||
| 12 | output there. (Or better yet, store device *names* since numbers can | ||
| 13 | change if you plug in or remove USB devices.) | ||
| 14 | |||
| 15 | Even without PmDefaults, a PortMidi API for Java is probably an | ||
| 16 | improvement over other Java libraries, but there is very little MIDI | ||
| 17 | development in Java, so I have not maintained this API. The only thing | ||
| 18 | probably seriously wrong now is an interface to the | ||
| 19 | Pm_CreateVirtualInput and Pm_CreateVirtualOutput functions, which are | ||
| 20 | new additions. | ||
| 21 | |||
| 22 | I will leave the code here, and if there is a demand, please either | ||
| 23 | update it or let your needs be known. Perhaps I or someone can help. | ||
| 24 | |||
| 25 | ================================================================== | ||
| 26 | |||
| 27 | BUILDING Java EXTERNAL LIBRARY | ||
| 28 | |||
| 29 | You must have a JDK installed (Java development kit including javac | ||
| 30 | (the Java compiler), jni.h, etc. | ||
| 31 | |||
| 32 | Test java on the command line, e.g., type: javac -version | ||
| 33 | |||
| 34 | Enable these options in the main CMakeLists.txt file (run CMake | ||
| 35 | from your top-level repository directory): | ||
| 36 | BUILD_JAVA_NATIVE_INTERFACE | ||
| 37 | In my Ubuntu linux with jdk-15, ccmake was unable to find my JDK, so | ||
| 38 | I have to manually set CMake variables as follows (type 't' to see | ||
| 39 | these in ccmake): | ||
| 40 | JAVA_AWT_INCLUDE_PATH /usr/lib/jvm/jdk-15/include | ||
| 41 | JAVA_AWT_LIBRARY /usr/lib/jvm/jdk-15/lib | ||
| 42 | JAVA_INCLUDE_PATH /usr/lib/jvm/jdk-15/include | ||
| 43 | JAVA_INCLUDE_PATH2 /usr/lib/jvm/jdk-15/include | ||
| 44 | JAVA_JVM_LIBRARY /usr/lib/jvm/jdk-15/lib | ||
| 45 | Of course, your paths may differ. | ||
| 46 | |||
| 47 | |||
| 48 | ---- old implementation notes ---- | ||
| 49 | |||
| 50 | For Windows, we use the free software JavaExe.exe. The copy here was | ||
| 51 | downloaded from | ||
| 52 | |||
| 53 | http://software.techrepublic.com.com/abstract.aspx?kw=javaexe&docid=767485 | ||
| 54 | |||
| 55 | I found this page by visiting http://software.techrepublic.com.com and | ||
| 56 | searching in the "Software" category for "JavaExe" | ||
| 57 | |||
| 58 | JavaExe works by placing the JavaExe.exe file in the directory with the | ||
| 59 | Java application jar file and then *renaming* JavaExe.exe to the name | ||
| 60 | of the jar file, but keeping the .exe extension. (See make.bat for this | ||
| 61 | step.) Documentation for JavaExe can be obtained by downloading the | ||
| 62 | whole program from the URL(s) above. | ||
diff --git a/portmidi/pm_java/jportmidi/JPortMidi.java b/portmidi/pm_java/jportmidi/JPortMidi.java new file mode 100644 index 0000000..7116e19 --- /dev/null +++ b/portmidi/pm_java/jportmidi/JPortMidi.java | |||
| @@ -0,0 +1,541 @@ | |||
| 1 | package jportmidi; | ||
| 2 | |||
| 3 | /* PortMidi is a general class intended for any Java program using | ||
| 4 | the PortMidi library. It encapsulates JPortMidiApi with a more | ||
| 5 | object-oriented interface. A single PortMidi object can manage | ||
| 6 | up to one input stream and one output stream. | ||
| 7 | |||
| 8 | This class is not safely callable from multiple threads. It | ||
| 9 | is the client's responsibility to periodically call the Poll | ||
| 10 | method which checks for midi input and handles it. | ||
| 11 | */ | ||
| 12 | |||
| 13 | import jportmidi.*; | ||
| 14 | import jportmidi.JPortMidiApi.*; | ||
| 15 | |||
| 16 | public class JPortMidi { | ||
| 17 | |||
| 18 | // timecode to send message immediately | ||
| 19 | public final int NOW = 0; | ||
| 20 | |||
| 21 | // midi codes | ||
| 22 | public final int MIDI_NOTE_OFF = 0x80; | ||
| 23 | public final int MIDI_NOTE_ON = 0x90; | ||
| 24 | public final int CTRL_ALL_OFF = 123; | ||
| 25 | public final int MIDI_PITCH_BEND = 0xE0; | ||
| 26 | public final int MIDI_CLOCK = 0xF8; | ||
| 27 | public final int MIDI_CONTROL = 0xB0; | ||
| 28 | public final int MIDI_PROGRAM = 0xC0; | ||
| 29 | public final int MIDI_START = 0xFA; | ||
| 30 | public final int MIDI_STOP = 0xFC; | ||
| 31 | public final int MIDI_POLY_TOUCH = 0xA0; | ||
| 32 | public final int MIDI_TOUCH = 0xD0; | ||
| 33 | |||
| 34 | // error code -- cannot refresh device list while stream is open: | ||
| 35 | public final int pmStreamOpen = -5000; | ||
| 36 | public final int pmOutputNotOpen = -4999; | ||
| 37 | |||
| 38 | // access to JPortMidiApi is through a single, global instance | ||
| 39 | private static JPortMidiApi pm; | ||
| 40 | // a reference count tracks how many objects have it open | ||
| 41 | private static int pmRefCount = 0; | ||
| 42 | private static int openCount = 0; | ||
| 43 | |||
| 44 | public int error; // user can check here for error codes | ||
| 45 | private PortMidiStream input; | ||
| 46 | private PortMidiStream output; | ||
| 47 | private PmEvent buffer; | ||
| 48 | protected int timestamp; // remember timestamp from incoming messages | ||
| 49 | protected boolean trace = false; // used to print midi msgs for debugging | ||
| 50 | |||
| 51 | |||
| 52 | public JPortMidi() throws JPortMidiException { | ||
| 53 | if (pmRefCount == 0) { | ||
| 54 | pm = new JPortMidiApi(); | ||
| 55 | pmRefCount++; | ||
| 56 | System.out.println("Calling Pm_Initialize"); | ||
| 57 | checkError(pm.Pm_Initialize()); | ||
| 58 | System.out.println("Called Pm_Initialize"); | ||
| 59 | } | ||
| 60 | buffer = new PmEvent(); | ||
| 61 | } | ||
| 62 | |||
| 63 | public boolean getTrace() { return trace; } | ||
| 64 | |||
| 65 | // set the trace flag and return previous value | ||
| 66 | public boolean setTrace(boolean flag) { | ||
| 67 | boolean previous = trace; | ||
| 68 | trace = flag; | ||
| 69 | return previous; | ||
| 70 | } | ||
| 71 | |||
| 72 | // WARNING: you must not call this if any devices are open | ||
| 73 | public void refreshDeviceLists() | ||
| 74 | throws JPortMidiException | ||
| 75 | { | ||
| 76 | if (openCount > 0) { | ||
| 77 | throw new JPortMidiException(pmStreamOpen, | ||
| 78 | "RefreshDeviceLists called while stream is open"); | ||
| 79 | } | ||
| 80 | if (trace) System.out.println("Pm_Terminate"); | ||
| 81 | checkError(pm.Pm_Terminate()); | ||
| 82 | if (trace) System.out.println("Pm_Initialize"); | ||
| 83 | checkError(pm.Pm_Initialize()); | ||
| 84 | } | ||
| 85 | |||
| 86 | // there is no control over when/whether this is called, but it seems | ||
| 87 | // to be a good idea to close things when this object is collected | ||
| 88 | public void finalize() { | ||
| 89 | if (input != null) { | ||
| 90 | error = pm.Pm_Close(input); | ||
| 91 | } | ||
| 92 | if (input != null) { | ||
| 93 | int rslt = pm.Pm_Close(output); | ||
| 94 | // we may lose an error code from closing output, but don't | ||
| 95 | // lose any real error from closing input... | ||
| 96 | if (error == pm.pmNoError) error = rslt; | ||
| 97 | } | ||
| 98 | pmRefCount--; | ||
| 99 | if (pmRefCount == 0) { | ||
| 100 | error = pm.Pm_Terminate(); | ||
| 101 | } | ||
| 102 | } | ||
| 103 | |||
| 104 | int checkError(int err) throws JPortMidiException | ||
| 105 | { | ||
| 106 | // note that Pm_Read and Pm_Write return positive result values | ||
| 107 | // which are not errors, so compare with >= | ||
| 108 | if (err >= pm.pmNoError) return err; | ||
| 109 | if (err == pm.pmHostError) { | ||
| 110 | throw new JPortMidiException(err, pm.Pm_GetHostErrorText()); | ||
| 111 | } else { | ||
| 112 | throw new JPortMidiException(err, pm.Pm_GetErrorText(err)); | ||
| 113 | } | ||
| 114 | } | ||
| 115 | |||
| 116 | // ******** ACCESS TO TIME *********** | ||
| 117 | |||
| 118 | public void timeStart(int resolution) throws JPortMidiException { | ||
| 119 | checkError(pm.Pt_TimeStart(resolution)); | ||
| 120 | } | ||
| 121 | |||
| 122 | public void timeStop() throws JPortMidiException { | ||
| 123 | checkError(pm.Pt_TimeStop()); | ||
| 124 | } | ||
| 125 | |||
| 126 | public int timeGet() { | ||
| 127 | return pm.Pt_Time(); | ||
| 128 | } | ||
| 129 | |||
| 130 | public boolean timeStarted() { | ||
| 131 | return pm.Pt_TimeStarted(); | ||
| 132 | } | ||
| 133 | |||
| 134 | // ******* QUERY DEVICE INFORMATION ********* | ||
| 135 | |||
| 136 | public int countDevices() throws JPortMidiException { | ||
| 137 | return checkError(pm.Pm_CountDevices()); | ||
| 138 | } | ||
| 139 | |||
| 140 | public int getDefaultInputDeviceID() throws JPortMidiException { | ||
| 141 | return checkError(pm.Pm_GetDefaultInputDeviceID()); | ||
| 142 | } | ||
| 143 | |||
| 144 | public int getDefaultOutputDeviceID() throws JPortMidiException { | ||
| 145 | return checkError(pm.Pm_GetDefaultOutputDeviceID()); | ||
| 146 | } | ||
| 147 | |||
| 148 | public String getDeviceInterf(int i) { | ||
| 149 | return pm.Pm_GetDeviceInterf(i); | ||
| 150 | } | ||
| 151 | |||
| 152 | public String getDeviceName(int i) { | ||
| 153 | return pm.Pm_GetDeviceName(i); | ||
| 154 | } | ||
| 155 | |||
| 156 | public boolean getDeviceInput(int i) { | ||
| 157 | return pm.Pm_GetDeviceInput(i); | ||
| 158 | } | ||
| 159 | |||
| 160 | public boolean getDeviceOutput(int i) { | ||
| 161 | return pm.Pm_GetDeviceOutput(i); | ||
| 162 | } | ||
| 163 | |||
| 164 | // ********** MIDI INTERFACE ************ | ||
| 165 | |||
| 166 | public boolean isOpenInput() { | ||
| 167 | return input != null; | ||
| 168 | } | ||
| 169 | |||
| 170 | public void openInput(int inputDevice, int bufferSize) | ||
| 171 | throws JPortMidiException | ||
| 172 | { | ||
| 173 | openInput(inputDevice, "", bufferSize); | ||
| 174 | } | ||
| 175 | |||
| 176 | public void openInput(int inputDevice, String inputDriverInfo, int bufferSize) | ||
| 177 | throws JPortMidiException | ||
| 178 | { | ||
| 179 | if (isOpenInput()) pm.Pm_Close(input); | ||
| 180 | else input = new PortMidiStream(); | ||
| 181 | if (trace) { | ||
| 182 | System.out.println("openInput " + getDeviceName(inputDevice)); | ||
| 183 | } | ||
| 184 | checkError(pm.Pm_OpenInput(input, inputDevice, | ||
| 185 | inputDriverInfo, bufferSize)); | ||
| 186 | // if no exception, then increase count of open streams | ||
| 187 | openCount++; | ||
| 188 | } | ||
| 189 | |||
| 190 | public boolean isOpenOutput() { | ||
| 191 | return output != null; | ||
| 192 | } | ||
| 193 | |||
| 194 | public void openOutput(int outputDevice, int bufferSize, int latency) | ||
| 195 | throws JPortMidiException | ||
| 196 | { | ||
| 197 | openOutput(outputDevice, "", bufferSize, latency); | ||
| 198 | } | ||
| 199 | |||
| 200 | public void openOutput(int outputDevice, String outputDriverInfo, | ||
| 201 | int bufferSize, int latency) throws JPortMidiException { | ||
| 202 | if (isOpenOutput()) pm.Pm_Close(output); | ||
| 203 | else output = new PortMidiStream(); | ||
| 204 | if (trace) { | ||
| 205 | System.out.println("openOutput " + getDeviceName(outputDevice)); | ||
| 206 | } | ||
| 207 | checkError(pm.Pm_OpenOutput(output, outputDevice, outputDriverInfo, | ||
| 208 | bufferSize, latency)); | ||
| 209 | // if no exception, then increase count of open streams | ||
| 210 | openCount++; | ||
| 211 | } | ||
| 212 | |||
| 213 | public void setFilter(int filters) throws JPortMidiException { | ||
| 214 | if (input == null) return; // no effect if input not open | ||
| 215 | checkError(pm.Pm_SetFilter(input, filters)); | ||
| 216 | } | ||
| 217 | |||
| 218 | public void setChannelMask(int mask) throws JPortMidiException { | ||
| 219 | if (input == null) return; // no effect if input not open | ||
| 220 | checkError(pm.Pm_SetChannelMask(input, mask)); | ||
| 221 | } | ||
| 222 | |||
| 223 | public void abort() throws JPortMidiException { | ||
| 224 | if (output == null) return; // no effect if output not open | ||
| 225 | checkError(pm.Pm_Abort(output)); | ||
| 226 | } | ||
| 227 | |||
| 228 | // In keeping with the idea that this class represents an input and output, | ||
| 229 | // there are separate Close methods for input and output streams, avoiding | ||
| 230 | // the need for clients to ever deal directly with a stream object | ||
| 231 | public void closeInput() throws JPortMidiException { | ||
| 232 | if (input == null) return; // no effect if input not open | ||
| 233 | checkError(pm.Pm_Close(input)); | ||
| 234 | input = null; | ||
| 235 | openCount--; | ||
| 236 | } | ||
| 237 | |||
| 238 | public void closeOutput() throws JPortMidiException { | ||
| 239 | if (output == null) return; // no effect if output not open | ||
| 240 | checkError(pm.Pm_Close(output)); | ||
| 241 | output = null; | ||
| 242 | openCount--; | ||
| 243 | } | ||
| 244 | |||
| 245 | // Poll should be called by client to process input messages (if any) | ||
| 246 | public void poll() throws JPortMidiException { | ||
| 247 | if (input == null) return; // does nothing until input is opened | ||
| 248 | while (true) { | ||
| 249 | int rslt = pm.Pm_Read(input, buffer); | ||
| 250 | checkError(rslt); | ||
| 251 | if (rslt == 0) return; // no more messages | ||
| 252 | handleMidiIn(buffer); | ||
| 253 | } | ||
| 254 | } | ||
| 255 | |||
| 256 | public void writeShort(int when, int msg) throws JPortMidiException { | ||
| 257 | if (output == null) | ||
| 258 | throw new JPortMidiException(pmOutputNotOpen, | ||
| 259 | "Output stream not open"); | ||
| 260 | if (trace) { | ||
| 261 | System.out.println("writeShort: " + Integer.toHexString(msg)); | ||
| 262 | } | ||
| 263 | checkError(pm.Pm_WriteShort(output, when, msg)); | ||
| 264 | } | ||
| 265 | |||
| 266 | public void writeSysEx(int when, byte msg[]) throws JPortMidiException { | ||
| 267 | if (output == null) | ||
| 268 | throw new JPortMidiException(pmOutputNotOpen, | ||
| 269 | "Output stream not open"); | ||
| 270 | if (trace) { | ||
| 271 | System.out.print("writeSysEx: "); | ||
| 272 | for (int i = 0; i < msg.length; i++) { | ||
| 273 | System.out.print(Integer.toHexString(msg[i])); | ||
| 274 | } | ||
| 275 | System.out.print("\n"); | ||
| 276 | } | ||
| 277 | checkError(pm.Pm_WriteSysEx(output, when, msg)); | ||
| 278 | } | ||
| 279 | |||
| 280 | public int midiChanMessage(int chan, int status, int data1, int data2) { | ||
| 281 | return (((data2 << 16) & 0xFF0000) | | ||
| 282 | ((data1 << 8) & 0xFF00) | | ||
| 283 | (status & 0xF0) | | ||
| 284 | (chan & 0xF)); | ||
| 285 | } | ||
| 286 | |||
| 287 | public int midiMessage(int status, int data1, int data2) { | ||
| 288 | return ((((data2) << 16) & 0xFF0000) | | ||
| 289 | (((data1) << 8) & 0xFF00) | | ||
| 290 | ((status) & 0xFF)); | ||
| 291 | } | ||
| 292 | |||
| 293 | public void midiAllOff(int channel) throws JPortMidiException { | ||
| 294 | midiAllOff(channel, NOW); | ||
| 295 | } | ||
| 296 | |||
| 297 | public void midiAllOff(int chan, int when) throws JPortMidiException { | ||
| 298 | writeShort(when, midiChanMessage(chan, MIDI_CONTROL, CTRL_ALL_OFF, 0)); | ||
| 299 | } | ||
| 300 | |||
| 301 | public void midiPitchBend(int chan, int value) throws JPortMidiException { | ||
| 302 | midiPitchBend(chan, value, NOW); | ||
| 303 | } | ||
| 304 | |||
| 305 | public void midiPitchBend(int chan, int value, int when) | ||
| 306 | throws JPortMidiException { | ||
| 307 | writeShort(when, | ||
| 308 | midiChanMessage(chan, MIDI_PITCH_BEND, value, value >> 7)); | ||
| 309 | } | ||
| 310 | |||
| 311 | public void midiClock() throws JPortMidiException { | ||
| 312 | midiClock(NOW); | ||
| 313 | } | ||
| 314 | |||
| 315 | public void midiClock(int when) throws JPortMidiException { | ||
| 316 | writeShort(when, midiMessage(MIDI_CLOCK, 0, 0)); | ||
| 317 | } | ||
| 318 | |||
| 319 | public void midiControl(int chan, int control, int value) | ||
| 320 | throws JPortMidiException { | ||
| 321 | midiControl(chan, control, value, NOW); | ||
| 322 | } | ||
| 323 | |||
| 324 | public void midiControl(int chan, int control, int value, int when) | ||
| 325 | throws JPortMidiException { | ||
| 326 | writeShort(when, midiChanMessage(chan, MIDI_CONTROL, control, value)); | ||
| 327 | } | ||
| 328 | |||
| 329 | public void midiNote(int chan, int pitch, int vel) | ||
| 330 | throws JPortMidiException { | ||
| 331 | midiNote(chan, pitch, vel, NOW); | ||
| 332 | } | ||
| 333 | |||
| 334 | public void midiNote(int chan, int pitch, int vel, int when) | ||
| 335 | throws JPortMidiException { | ||
| 336 | writeShort(when, midiChanMessage(chan, MIDI_NOTE_ON, pitch, vel)); | ||
| 337 | } | ||
| 338 | |||
| 339 | public void midiProgram(int chan, int program) | ||
| 340 | throws JPortMidiException { | ||
| 341 | midiProgram(chan, program, NOW); | ||
| 342 | } | ||
| 343 | |||
| 344 | public void midiProgram(int chan, int program, int when) | ||
| 345 | throws JPortMidiException { | ||
| 346 | writeShort(when, midiChanMessage(chan, MIDI_PROGRAM, program, 0)); | ||
| 347 | } | ||
| 348 | |||
| 349 | public void midiStart() | ||
| 350 | throws JPortMidiException { | ||
| 351 | midiStart(NOW); | ||
| 352 | } | ||
| 353 | |||
| 354 | public void midiStart(int when) | ||
| 355 | throws JPortMidiException { | ||
| 356 | writeShort(when, midiMessage(MIDI_START, 0, 0)); | ||
| 357 | } | ||
| 358 | |||
| 359 | public void midiStop() | ||
| 360 | throws JPortMidiException { | ||
| 361 | midiStop(NOW); | ||
| 362 | } | ||
| 363 | |||
| 364 | public void midiStop(int when) | ||
| 365 | throws JPortMidiException { | ||
| 366 | writeShort(when, midiMessage(MIDI_STOP, 0, 0)); | ||
| 367 | } | ||
| 368 | |||
| 369 | public void midiPolyTouch(int chan, int key, int value) | ||
| 370 | throws JPortMidiException { | ||
| 371 | midiPolyTouch(chan, key, value, NOW); | ||
| 372 | } | ||
| 373 | |||
| 374 | public void midiPolyTouch(int chan, int key, int value, int when) | ||
| 375 | throws JPortMidiException { | ||
| 376 | writeShort(when, midiChanMessage(chan, MIDI_POLY_TOUCH, key, value)); | ||
| 377 | } | ||
| 378 | |||
| 379 | public void midiTouch(int chan, int value) | ||
| 380 | throws JPortMidiException { | ||
| 381 | midiTouch(chan, value, NOW); | ||
| 382 | } | ||
| 383 | |||
| 384 | public void midiTouch(int chan, int value, int when) | ||
| 385 | throws JPortMidiException { | ||
| 386 | writeShort(when, midiChanMessage(chan, MIDI_TOUCH, value, 0)); | ||
| 387 | } | ||
| 388 | |||
| 389 | // ****** now we implement the message handlers ****** | ||
| 390 | |||
| 391 | // an array for incoming sysex messages that can grow. | ||
| 392 | // The downside is that after getting a message, we | ||
| 393 | |||
| 394 | private byte sysexBuffer[] = null; | ||
| 395 | private int sysexBufferIndex = 0; | ||
| 396 | |||
| 397 | void sysexBufferReset() { | ||
| 398 | sysexBufferIndex = 0; | ||
| 399 | if (sysexBuffer == null) sysexBuffer = new byte[256]; | ||
| 400 | } | ||
| 401 | |||
| 402 | void sysexBufferCheck() { | ||
| 403 | if (sysexBuffer.length < sysexBufferIndex + 4) { | ||
| 404 | byte bigger[] = new byte[sysexBuffer.length * 2]; | ||
| 405 | for (int i = 0; i < sysexBufferIndex; i++) { | ||
| 406 | bigger[i] = sysexBuffer[i]; | ||
| 407 | } | ||
| 408 | sysexBuffer = bigger; | ||
| 409 | } | ||
| 410 | // now we have space to write some bytes | ||
| 411 | } | ||
| 412 | |||
| 413 | // call this to insert Sysex and EOX status bytes | ||
| 414 | // call sysexBufferAppendBytes to insert anything else | ||
| 415 | void sysexBufferAppendStatus(byte status) { | ||
| 416 | sysexBuffer[sysexBufferIndex++] = status; | ||
| 417 | } | ||
| 418 | |||
| 419 | void sysexBufferAppendBytes(int msg, int len) { | ||
| 420 | for (int i = 0; i < len; i++) { | ||
| 421 | byte b = (byte) msg; | ||
| 422 | if ((msg & 0x80) != 0) { | ||
| 423 | if (b == 0xF7) { // end of sysex | ||
| 424 | sysexBufferAppendStatus(b); | ||
| 425 | sysex(sysexBuffer, sysexBufferIndex); | ||
| 426 | return; | ||
| 427 | } | ||
| 428 | // recursively handle embedded real-time messages | ||
| 429 | PmEvent buffer = new PmEvent(); | ||
| 430 | buffer.timestamp = timestamp; | ||
| 431 | buffer.message = b; | ||
| 432 | handleMidiIn(buffer); | ||
| 433 | } else { | ||
| 434 | sysexBuffer[sysexBufferIndex++] = b; | ||
| 435 | } | ||
| 436 | msg = msg >> 8; | ||
| 437 | } | ||
| 438 | } | ||
| 439 | |||
| 440 | void sysexBegin(int msg) { | ||
| 441 | sysexBufferReset(); // start from 0, we have at least 256 bytes now | ||
| 442 | sysexBufferAppendStatus((byte) (msg & 0xFF)); // first byte is special | ||
| 443 | sysexBufferAppendBytes(msg >> 8, 3); // process remaining bytes | ||
| 444 | } | ||
| 445 | |||
| 446 | public void handleMidiIn(PmEvent buffer) | ||
| 447 | { | ||
| 448 | if (trace) { | ||
| 449 | System.out.println("handleMidiIn: " + | ||
| 450 | Integer.toHexString(buffer.message)); | ||
| 451 | } | ||
| 452 | // rather than pass timestamps to every handler, where typically | ||
| 453 | // timestamps are ignored, just save the timestamp as a member | ||
| 454 | // variable where methods can access it if they want it | ||
| 455 | timestamp = buffer.timestamp; | ||
| 456 | int status = buffer.message & 0xFF; | ||
| 457 | if (status < 0x80) { | ||
| 458 | sysexBufferCheck(); // make enough space | ||
| 459 | sysexBufferAppendBytes(buffer.message, 4); // process 4 bytes | ||
| 460 | return; | ||
| 461 | } | ||
| 462 | int command = status & 0xF0; | ||
| 463 | int channel = status & 0x0F; | ||
| 464 | int data1 = (buffer.message >> 8) & 0xFF; | ||
| 465 | int data2 = (buffer.message >> 16) & 0xFF; | ||
| 466 | switch (command) { | ||
| 467 | case MIDI_NOTE_OFF: | ||
| 468 | noteOff(channel, data1, data2); break; | ||
| 469 | case MIDI_NOTE_ON: | ||
| 470 | if (data2 > 0) { | ||
| 471 | noteOn(channel, data1, data2); break; | ||
| 472 | } else { | ||
| 473 | noteOff(channel, data1); | ||
| 474 | } | ||
| 475 | break; | ||
| 476 | case MIDI_CONTROL: | ||
| 477 | control(channel, data1, data2); break; | ||
| 478 | case MIDI_POLY_TOUCH: | ||
| 479 | polyTouch(channel, data1, data2); break; | ||
| 480 | case MIDI_TOUCH: | ||
| 481 | touch(channel, data1); break; | ||
| 482 | case MIDI_PITCH_BEND: | ||
| 483 | pitchBend(channel, (data1 + (data2 << 7)) - 8192); break; | ||
| 484 | case MIDI_PROGRAM: | ||
| 485 | program(channel, data1); break; | ||
| 486 | case 0xF0: | ||
| 487 | switch (channel) { | ||
| 488 | case 0: sysexBegin(buffer.message); break; | ||
| 489 | case 1: mtcQuarterFrame(data1); | ||
| 490 | case 2: songPosition(data1 + (data2 << 7)); break; | ||
| 491 | case 3: songSelect(data1); break; | ||
| 492 | case 4: /* unused */ break; | ||
| 493 | case 5: /* unused */ break; | ||
| 494 | case 6: tuneRequest(); break; | ||
| 495 | case 7: sysexBufferAppendBytes(buffer.message, buffer.message); break; | ||
| 496 | case 8: clock(); break; | ||
| 497 | case 9: tick(); break; | ||
| 498 | case 0xA: clockStart(); break; | ||
| 499 | case 0xB: clockContinue(); break; | ||
| 500 | case 0xC: clockStop(); break; | ||
| 501 | case 0xD: /* unused */ break; | ||
| 502 | case 0xE: activeSense(); break; | ||
| 503 | case 0xF: reset(); break; | ||
| 504 | } | ||
| 505 | } | ||
| 506 | } | ||
| 507 | |||
| 508 | // the value ranges from +8181 to -8192. The interpretation is | ||
| 509 | // synthesizer dependent. Often the range is +/- one whole step | ||
| 510 | // (two semitones), but the range is usually adjustable within | ||
| 511 | // the synthesizer. | ||
| 512 | void pitchBend(int channel, int value) { return; } | ||
| 513 | void control(int channel, int control, int value) { return; } | ||
| 514 | void noteOn(int channel, int pitch, int velocity) { return; } | ||
| 515 | // you can handle velocity in note-off if you want, but the default | ||
| 516 | // is to drop the velocity and call the simpler NoteOff handler | ||
| 517 | void noteOff(int channel, int pitch, int velocity) { | ||
| 518 | noteOff(channel, pitch); | ||
| 519 | } | ||
| 520 | // if the subclass wants to implement NoteOff with velocity, it | ||
| 521 | // should override the following to make sure all NoteOffs are handled | ||
| 522 | void noteOff(int channel, int pitch) { return; } | ||
| 523 | void program(int channel, int program) { return; } | ||
| 524 | // the byte array may be bigger than the message, length tells how | ||
| 525 | // many bytes in the array are part of the message | ||
| 526 | void sysex(byte[] msg, int length) { return; } | ||
| 527 | void polyTouch(int channel, int key, int value) { return; } | ||
| 528 | void touch(int channel, int value) { return; } | ||
| 529 | void mtcQuarterFrame(int value) { return; } | ||
| 530 | // the value is a 14-bit integer representing 16th notes | ||
| 531 | void songPosition(int value) { return; } | ||
| 532 | void songSelect(int value) { return; } | ||
| 533 | void tuneRequest() { return; } | ||
| 534 | void clock() { return; } // represents 1/24th of a quarter note | ||
| 535 | void tick() { return; } // represents 10ms | ||
| 536 | void clockStart() { return; } | ||
| 537 | void clockStop() { return; } | ||
| 538 | void clockContinue() { return; } | ||
| 539 | void activeSense() { return; } | ||
| 540 | void reset() { return; } | ||
| 541 | } | ||
diff --git a/portmidi/pm_java/jportmidi/JPortMidiApi.java b/portmidi/pm_java/jportmidi/JPortMidiApi.java new file mode 100644 index 0000000..45dd9d9 --- /dev/null +++ b/portmidi/pm_java/jportmidi/JPortMidiApi.java | |||
| @@ -0,0 +1,117 @@ | |||
| 1 | package jportmidi; | ||
| 2 | |||
| 3 | public class JPortMidiApi { | ||
| 4 | public static class PortMidiStream { | ||
| 5 | private long address; | ||
| 6 | } | ||
| 7 | public static class PmEvent { | ||
| 8 | public int message; | ||
| 9 | public int timestamp; | ||
| 10 | } | ||
| 11 | |||
| 12 | // PmError bindings | ||
| 13 | public final int pmNoError = 0; | ||
| 14 | public final int pmNoData = 0; | ||
| 15 | public final int pmGotData = -1; | ||
| 16 | public final int pmHostError = -10000; | ||
| 17 | public final int pmInvalidDeviceId = -9999; | ||
| 18 | public final int pmInsufficientMemory = -9998; | ||
| 19 | public final int pmBufferTooSmall = -9997; | ||
| 20 | public final int pmBufferOverflow = -9996; | ||
| 21 | public final int pmBadPtr = -9995; | ||
| 22 | public final int pmBadData = -9994; | ||
| 23 | public final int pmInternalError = -9993; | ||
| 24 | public final int pmBufferMaxSize = -9992; | ||
| 25 | |||
| 26 | static public native int Pm_Initialize(); | ||
| 27 | static public native int Pm_Terminate(); | ||
| 28 | static public native int Pm_HasHostError(PortMidiStream stream); | ||
| 29 | static public native String Pm_GetErrorText(int errnum); | ||
| 30 | static public native String Pm_GetHostErrorText(); | ||
| 31 | final int pmNoDevice = -1; | ||
| 32 | static public native int Pm_CountDevices(); | ||
| 33 | static public native int Pm_GetDefaultInputDeviceID(); | ||
| 34 | static public native int Pm_GetDefaultOutputDeviceID(); | ||
| 35 | static public native String Pm_GetDeviceInterf(int i); | ||
| 36 | static public native String Pm_GetDeviceName(int i); | ||
| 37 | static public native boolean Pm_GetDeviceInput(int i); | ||
| 38 | static public native boolean Pm_GetDeviceOutput(int i); | ||
| 39 | static public native int Pm_OpenInput(PortMidiStream stream, | ||
| 40 | int inputDevice, | ||
| 41 | String inputDriverInfo, | ||
| 42 | int bufferSize); | ||
| 43 | static public native int Pm_OpenOutput(PortMidiStream stream, | ||
| 44 | int outputDevice, | ||
| 45 | String outnputDriverInfo, | ||
| 46 | int bufferSize, | ||
| 47 | int latency); | ||
| 48 | final static public int PM_FILT_ACTIVE = (1 << 0x0E); | ||
| 49 | final static public int PM_FILT_SYSEX = (1 << 0x00); | ||
| 50 | final static public int PM_FILT_CLOCK = (1 << 0x08); | ||
| 51 | final static public int PM_FILT_PLAY = | ||
| 52 | (1 << 0x0A) | (1 << 0x0C) | (1 << 0x0B); | ||
| 53 | final static public int PM_FILT_TICK = (1 << 0x09); | ||
| 54 | final static public int PM_FILT_FD = (1 << 0x0D); | ||
| 55 | final static public int PM_FILT_UNDEFINED = PM_FILT_FD; | ||
| 56 | final static public int PM_FILT_RESET = (1 << 0x0F); | ||
| 57 | final static public int PM_FILT_REALTIME = | ||
| 58 | PM_FILT_ACTIVE | PM_FILT_SYSEX | PM_FILT_CLOCK; | ||
| 59 | final static public int PM_FILT_NOTE = (1 << 0x19) | (1 << 0x18); | ||
| 60 | final static public int PM_FILT_CHANNEL_AFTERTOUCH = (1 << 0x1D); | ||
| 61 | final static public int PM_FILT_POLY_AFTERTOUCH = (1 << 0x1A); | ||
| 62 | final static public int PM_FILT_AFTERTOUCH = | ||
| 63 | (PM_FILT_CHANNEL_AFTERTOUCH | PM_FILT_POLY_AFTERTOUCH); | ||
| 64 | final static public int PM_FILT_PROGRAM = (1 << 0x1C); | ||
| 65 | final static public int PM_FILT_CONTROL = (1 << 0x1B); | ||
| 66 | final static public int PM_FILT_PITCHBEND = (1 << 0x1E); | ||
| 67 | final static public int PM_FILT_MTC = (1 << 0x01); | ||
| 68 | final static public int PM_FILT_SONG_POSITION = (1 << 0x02); | ||
| 69 | final static public int PM_FILT_SONG_SELECT = (1 << 0x03); | ||
| 70 | final static public int PM_FILT_TUNE = (1 << 0x06); | ||
| 71 | final static public int PM_FILT_SYSTEMCOMMON = | ||
| 72 | (PM_FILT_MTC | PM_FILT_SONG_POSITION | | ||
| 73 | PM_FILT_SONG_SELECT | PM_FILT_TUNE); | ||
| 74 | static public native int Pm_SetFilter(PortMidiStream stream, int filters); | ||
| 75 | static public int Pm_Channel(int channel) { return 1 << channel; } | ||
| 76 | final static public native int Pm_SetChannelMask(PortMidiStream stream, | ||
| 77 | int mask); | ||
| 78 | final static public native int Pm_Abort(PortMidiStream stream); | ||
| 79 | final static public native int Pm_Close(PortMidiStream stream); | ||
| 80 | static public int Pm_Message(int status, int data1, int data2) { | ||
| 81 | return (((data2 << 16) & 0xFF0000) | | ||
| 82 | ((data1 << 8) & 0xFF00) | | ||
| 83 | (status & 0xFF)); | ||
| 84 | } | ||
| 85 | static public int Pm_MessageStatus(int msg) { | ||
| 86 | return msg & 0xFF; | ||
| 87 | } | ||
| 88 | static public int Pm_MessageData1(int msg) { | ||
| 89 | return (msg >> 8) & 0xFF; | ||
| 90 | } | ||
| 91 | static public int Pm_MessageData2(int msg) { | ||
| 92 | return (msg >> 16) & 0xFF; | ||
| 93 | } | ||
| 94 | // only supports reading one buffer at a time | ||
| 95 | static public native int Pm_Read(PortMidiStream stream, PmEvent buffer); | ||
| 96 | static public native int Pm_Poll(PortMidiStream stream); | ||
| 97 | // only supports writing one buffer at a time | ||
| 98 | static public native int Pm_Write(PortMidiStream stream, PmEvent buffer); | ||
| 99 | static public native int Pm_WriteShort(PortMidiStream stream, | ||
| 100 | int when, int msg); | ||
| 101 | static public native int Pm_WriteSysEx(PortMidiStream stream, | ||
| 102 | int when, byte msg[]); | ||
| 103 | |||
| 104 | public final int ptNoError = 0; | ||
| 105 | public final int ptAlreadyStarted = -10000; | ||
| 106 | public final int ptAlreadyStopped = -9999; | ||
| 107 | public final int PtInsufficientMemory = -9998; | ||
| 108 | static public native int Pt_TimeStart(int resolution); | ||
| 109 | static public native int Pt_TimeStop(); | ||
| 110 | static public native int Pt_Time(); | ||
| 111 | static public native boolean Pt_TimeStarted(); | ||
| 112 | static { | ||
| 113 | System.out.println("Loading pmjni"); | ||
| 114 | System.loadLibrary("pmjni"); | ||
| 115 | System.out.println("done loading pmjni"); | ||
| 116 | } | ||
| 117 | } | ||
diff --git a/portmidi/pm_java/jportmidi/JPortMidiException.java b/portmidi/pm_java/jportmidi/JPortMidiException.java new file mode 100644 index 0000000..9be8aaf --- /dev/null +++ b/portmidi/pm_java/jportmidi/JPortMidiException.java | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | // JPortMidiException -- thrown by JPortMidi methods | ||
| 2 | |||
| 3 | package jportmidi; | ||
| 4 | |||
| 5 | public class JPortMidiException extends Exception { | ||
| 6 | public int error = 0; | ||
| 7 | public JPortMidiException(int err, String msg) { | ||
| 8 | super(msg); | ||
| 9 | error = err; | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
diff --git a/portmidi/pm_java/make.bat b/portmidi/pm_java/make.bat new file mode 100644 index 0000000..ff15c2b --- /dev/null +++ b/portmidi/pm_java/make.bat | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | @echo off | ||
| 2 | |||
| 3 | rem This is an out-of-date script for Windows to build a Java application | ||
| 4 | rem (PmDefaults) with PortMidi external library.xb | ||
| 5 | |||
| 6 | rem Compile the java PortMidi interface classes. | ||
| 7 | javac jportmidi/*.java | ||
| 8 | |||
| 9 | rem Compile the pmdefaults application. | ||
| 10 | javac -classpath . pmdefaults/*.java | ||
| 11 | |||
| 12 | rem Temporarily copy the portmusic_logo.png file here to add to the jar file. | ||
| 13 | copy pmdefaults\portmusic_logo.png . > nul | ||
| 14 | |||
| 15 | rem Create a directory to hold the distribution. | ||
| 16 | mkdir win32 | ||
| 17 | |||
| 18 | rem Attempt to copy the interface DLL to the distribution directory. | ||
| 19 | |||
| 20 | if exist "..\release\pmjni.dll" goto have-dll | ||
| 21 | |||
| 22 | echo "ERROR: pmjni.dll not found!" | ||
| 23 | exit /b 1 | ||
| 24 | |||
| 25 | :have-dll | ||
| 26 | copy "..\release\pmjni.dll" win32\pmjni.dll > nul | ||
| 27 | |||
| 28 | rem Create a java archive (jar) file of the distribution. | ||
| 29 | jar cmf pmdefaults\manifest.txt win32\pmdefaults.jar pmdefaults\*.class portmusic_logo.png jportmidi\*.class | ||
| 30 | |||
| 31 | rem Clean up the temporary image file now that it is in the jar file. | ||
| 32 | del portmusic_logo.png | ||
| 33 | |||
| 34 | rem Copy the java execution code obtained from | ||
| 35 | rem http://devwizard.free.fr/html/en/JavaExe.html to the distribution | ||
| 36 | rem directory. The copy also renames the file to our desired executable | ||
| 37 | rem name. | ||
| 38 | copy JavaExe.exe win32\pmdefaults.exe > nul | ||
| 39 | |||
| 40 | rem Integrate the icon into the executable using UpdateRsrcJavaExe from | ||
| 41 | rem http://devwizard.free.fr | ||
| 42 | UpdateRsrcJavaExe -run -exe=win32\pmdefaults.exe -ico=pmdefaults\pmdefaults.ico | ||
| 43 | |||
| 44 | rem Copy the 32-bit windows read me file to the distribution directory. | ||
| 45 | copy pmdefaults\readme-win32.txt win32\README.txt > nul | ||
| 46 | |||
| 47 | rem Copy the license file to the distribution directory. | ||
| 48 | copy pmdefaults\pmdefaults-license.txt win32\license.txt > nul | ||
| 49 | |||
| 50 | echo "You can run pmdefaults.exe in win32" | ||
diff --git a/portmidi/pm_java/pmjni/jportmidi_JportMidiApi.h b/portmidi/pm_java/pmjni/jportmidi_JportMidiApi.h new file mode 100644 index 0000000..2208be6 --- /dev/null +++ b/portmidi/pm_java/pmjni/jportmidi_JportMidiApi.h | |||
| @@ -0,0 +1,293 @@ | |||
| 1 | /* DO NOT EDIT THIS FILE - it is machine generated */ | ||
| 2 | #include <jni.h> | ||
| 3 | /* Header for class jportmidi_JPortMidiApi */ | ||
| 4 | |||
| 5 | #ifndef _Included_jportmidi_JPortMidiApi | ||
| 6 | #define _Included_jportmidi_JPortMidiApi | ||
| 7 | #ifdef __cplusplus | ||
| 8 | extern "C" { | ||
| 9 | #endif | ||
| 10 | #undef jportmidi_JPortMidiApi_PM_FILT_ACTIVE | ||
| 11 | #define jportmidi_JPortMidiApi_PM_FILT_ACTIVE 16384L | ||
| 12 | #undef jportmidi_JPortMidiApi_PM_FILT_SYSEX | ||
| 13 | #define jportmidi_JPortMidiApi_PM_FILT_SYSEX 1L | ||
| 14 | #undef jportmidi_JPortMidiApi_PM_FILT_CLOCK | ||
| 15 | #define jportmidi_JPortMidiApi_PM_FILT_CLOCK 256L | ||
| 16 | #undef jportmidi_JPortMidiApi_PM_FILT_PLAY | ||
| 17 | #define jportmidi_JPortMidiApi_PM_FILT_PLAY 7168L | ||
| 18 | #undef jportmidi_JPortMidiApi_PM_FILT_TICK | ||
| 19 | #define jportmidi_JPortMidiApi_PM_FILT_TICK 512L | ||
| 20 | #undef jportmidi_JPortMidiApi_PM_FILT_FD | ||
| 21 | #define jportmidi_JPortMidiApi_PM_FILT_FD 8192L | ||
| 22 | #undef jportmidi_JPortMidiApi_PM_FILT_UNDEFINED | ||
| 23 | #define jportmidi_JPortMidiApi_PM_FILT_UNDEFINED 8192L | ||
| 24 | #undef jportmidi_JPortMidiApi_PM_FILT_RESET | ||
| 25 | #define jportmidi_JPortMidiApi_PM_FILT_RESET 32768L | ||
| 26 | #undef jportmidi_JPortMidiApi_PM_FILT_REALTIME | ||
| 27 | #define jportmidi_JPortMidiApi_PM_FILT_REALTIME 16641L | ||
| 28 | #undef jportmidi_JPortMidiApi_PM_FILT_NOTE | ||
| 29 | #define jportmidi_JPortMidiApi_PM_FILT_NOTE 50331648L | ||
| 30 | #undef jportmidi_JPortMidiApi_PM_FILT_CHANNEL_AFTERTOUCH | ||
| 31 | #define jportmidi_JPortMidiApi_PM_FILT_CHANNEL_AFTERTOUCH 536870912L | ||
| 32 | #undef jportmidi_JPortMidiApi_PM_FILT_POLY_AFTERTOUCH | ||
| 33 | #define jportmidi_JPortMidiApi_PM_FILT_POLY_AFTERTOUCH 67108864L | ||
| 34 | #undef jportmidi_JPortMidiApi_PM_FILT_AFTERTOUCH | ||
| 35 | #define jportmidi_JPortMidiApi_PM_FILT_AFTERTOUCH 603979776L | ||
| 36 | #undef jportmidi_JPortMidiApi_PM_FILT_PROGRAM | ||
| 37 | #define jportmidi_JPortMidiApi_PM_FILT_PROGRAM 268435456L | ||
| 38 | #undef jportmidi_JPortMidiApi_PM_FILT_CONTROL | ||
| 39 | #define jportmidi_JPortMidiApi_PM_FILT_CONTROL 134217728L | ||
| 40 | #undef jportmidi_JPortMidiApi_PM_FILT_PITCHBEND | ||
| 41 | #define jportmidi_JPortMidiApi_PM_FILT_PITCHBEND 1073741824L | ||
| 42 | #undef jportmidi_JPortMidiApi_PM_FILT_MTC | ||
| 43 | #define jportmidi_JPortMidiApi_PM_FILT_MTC 2L | ||
| 44 | #undef jportmidi_JPortMidiApi_PM_FILT_SONG_POSITION | ||
| 45 | #define jportmidi_JPortMidiApi_PM_FILT_SONG_POSITION 4L | ||
| 46 | #undef jportmidi_JPortMidiApi_PM_FILT_SONG_SELECT | ||
| 47 | #define jportmidi_JPortMidiApi_PM_FILT_SONG_SELECT 8L | ||
| 48 | #undef jportmidi_JPortMidiApi_PM_FILT_TUNE | ||
| 49 | #define jportmidi_JPortMidiApi_PM_FILT_TUNE 64L | ||
| 50 | #undef jportmidi_JPortMidiApi_PM_FILT_SYSTEMCOMMON | ||
| 51 | #define jportmidi_JPortMidiApi_PM_FILT_SYSTEMCOMMON 78L | ||
| 52 | /* | ||
| 53 | * Class: jportmidi_JPortMidiApi | ||
| 54 | * Method: Pm_Initialize | ||
| 55 | * Signature: ()I | ||
| 56 | */ | ||
| 57 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1Initialize | ||
| 58 | (JNIEnv *, jclass); | ||
| 59 | |||
| 60 | /* | ||
| 61 | * Class: jportmidi_JPortMidiApi | ||
| 62 | * Method: Pm_Terminate | ||
| 63 | * Signature: ()I | ||
| 64 | */ | ||
| 65 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1Terminate | ||
| 66 | (JNIEnv *, jclass); | ||
| 67 | |||
| 68 | /* | ||
| 69 | * Class: jportmidi_JPortMidiApi | ||
| 70 | * Method: Pm_HasHostError | ||
| 71 | * Signature: (Ljportmidi/JPortMidiApi/PortMidiStream;)I | ||
| 72 | */ | ||
| 73 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1HasHostError | ||
| 74 | (JNIEnv *, jclass, jobject); | ||
| 75 | |||
| 76 | /* | ||
| 77 | * Class: jportmidi_JPortMidiApi | ||
| 78 | * Method: Pm_GetErrorText | ||
| 79 | * Signature: (I)Ljava/lang/String; | ||
| 80 | */ | ||
| 81 | JNIEXPORT jstring JNICALL Java_jportmidi_JPortMidiApi_Pm_1GetErrorText | ||
| 82 | (JNIEnv *, jclass, jint); | ||
| 83 | |||
| 84 | /* | ||
| 85 | * Class: jportmidi_JPortMidiApi | ||
| 86 | * Method: Pm_GetHostErrorText | ||
| 87 | * Signature: ()Ljava/lang/String; | ||
| 88 | */ | ||
| 89 | JNIEXPORT jstring JNICALL Java_jportmidi_JPortMidiApi_Pm_1GetHostErrorText | ||
| 90 | (JNIEnv *, jclass); | ||
| 91 | |||
| 92 | /* | ||
| 93 | * Class: jportmidi_JPortMidiApi | ||
| 94 | * Method: Pm_CountDevices | ||
| 95 | * Signature: ()I | ||
| 96 | */ | ||
| 97 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1CountDevices | ||
| 98 | (JNIEnv *, jclass); | ||
| 99 | |||
| 100 | /* | ||
| 101 | * Class: jportmidi_JPortMidiApi | ||
| 102 | * Method: Pm_GetDefaultInputDeviceID | ||
| 103 | * Signature: ()I | ||
| 104 | */ | ||
| 105 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1GetDefaultInputDeviceID | ||
| 106 | (JNIEnv *, jclass); | ||
| 107 | |||
| 108 | /* | ||
| 109 | * Class: jportmidi_JPortMidiApi | ||
| 110 | * Method: Pm_GetDefaultOutputDeviceID | ||
| 111 | * Signature: ()I | ||
| 112 | */ | ||
| 113 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1GetDefaultOutputDeviceID | ||
| 114 | (JNIEnv *, jclass); | ||
| 115 | |||
| 116 | /* | ||
| 117 | * Class: jportmidi_JPortMidiApi | ||
| 118 | * Method: Pm_GetDeviceInterf | ||
| 119 | * Signature: (I)Ljava/lang/String; | ||
| 120 | */ | ||
| 121 | JNIEXPORT jstring JNICALL Java_jportmidi_JPortMidiApi_Pm_1GetDeviceInterf | ||
| 122 | (JNIEnv *, jclass, jint); | ||
| 123 | |||
| 124 | /* | ||
| 125 | * Class: jportmidi_JPortMidiApi | ||
| 126 | * Method: Pm_GetDeviceName | ||
| 127 | * Signature: (I)Ljava/lang/String; | ||
| 128 | */ | ||
| 129 | JNIEXPORT jstring JNICALL Java_jportmidi_JPortMidiApi_Pm_1GetDeviceName | ||
| 130 | (JNIEnv *, jclass, jint); | ||
| 131 | |||
| 132 | /* | ||
| 133 | * Class: jportmidi_JPortMidiApi | ||
| 134 | * Method: Pm_GetDeviceInput | ||
| 135 | * Signature: (I)Z | ||
| 136 | */ | ||
| 137 | JNIEXPORT jboolean JNICALL Java_jportmidi_JPortMidiApi_Pm_1GetDeviceInput | ||
| 138 | (JNIEnv *, jclass, jint); | ||
| 139 | |||
| 140 | /* | ||
| 141 | * Class: jportmidi_JPortMidiApi | ||
| 142 | * Method: Pm_GetDeviceOutput | ||
| 143 | * Signature: (I)Z | ||
| 144 | */ | ||
| 145 | JNIEXPORT jboolean JNICALL Java_jportmidi_JPortMidiApi_Pm_1GetDeviceOutput | ||
| 146 | (JNIEnv *, jclass, jint); | ||
| 147 | |||
| 148 | /* | ||
| 149 | * Class: jportmidi_JPortMidiApi | ||
| 150 | * Method: Pm_OpenInput | ||
| 151 | * Signature: (Ljportmidi/JPortMidiApi/PortMidiStream;ILjava/lang/String;I)I | ||
| 152 | */ | ||
| 153 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1OpenInput | ||
| 154 | (JNIEnv *, jclass, jobject, jint, jstring, jint); | ||
| 155 | |||
| 156 | /* | ||
| 157 | * Class: jportmidi_JPortMidiApi | ||
| 158 | * Method: Pm_OpenOutput | ||
| 159 | * Signature: (Ljportmidi/JPortMidiApi/PortMidiStream;ILjava/lang/String;II)I | ||
| 160 | */ | ||
| 161 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1OpenOutput | ||
| 162 | (JNIEnv *, jclass, jobject, jint, jstring, jint, jint); | ||
| 163 | |||
| 164 | /* | ||
| 165 | * Class: jportmidi_JPortMidiApi | ||
| 166 | * Method: Pm_SetFilter | ||
| 167 | * Signature: (Ljportmidi/JPortMidiApi/PortMidiStream;I)I | ||
| 168 | */ | ||
| 169 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1SetFilter | ||
| 170 | (JNIEnv *, jclass, jobject, jint); | ||
| 171 | |||
| 172 | /* | ||
| 173 | * Class: jportmidi_JPortMidiApi | ||
| 174 | * Method: Pm_SetChannelMask | ||
| 175 | * Signature: (Ljportmidi/JPortMidiApi/PortMidiStream;I)I | ||
| 176 | */ | ||
| 177 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1SetChannelMask | ||
| 178 | (JNIEnv *, jclass, jobject, jint); | ||
| 179 | |||
| 180 | /* | ||
| 181 | * Class: jportmidi_JPortMidiApi | ||
| 182 | * Method: Pm_Abort | ||
| 183 | * Signature: (Ljportmidi/JPortMidiApi/PortMidiStream;)I | ||
| 184 | */ | ||
| 185 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1Abort | ||
| 186 | (JNIEnv *, jclass, jobject); | ||
| 187 | |||
| 188 | /* | ||
| 189 | * Class: jportmidi_JPortMidiApi | ||
| 190 | * Method: Pm_Close | ||
| 191 | * Signature: (Ljportmidi/JPortMidiApi/PortMidiStream;)I | ||
| 192 | */ | ||
| 193 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1Close | ||
| 194 | (JNIEnv *, jclass, jobject); | ||
| 195 | |||
| 196 | /* | ||
| 197 | * Class: jportmidi_JPortMidiApi | ||
| 198 | * Method: Pm_Read | ||
| 199 | * Signature: (Ljportmidi/JPortMidiApi/PortMidiStream;Ljportmidi/JPortMidiApi/PmEvent;)I | ||
| 200 | */ | ||
| 201 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1Read | ||
| 202 | (JNIEnv *, jclass, jobject, jobject); | ||
| 203 | |||
| 204 | /* | ||
| 205 | * Class: jportmidi_JPortMidiApi | ||
| 206 | * Method: Pm_Poll | ||
| 207 | * Signature: (Ljportmidi/JPortMidiApi/PortMidiStream;)I | ||
| 208 | */ | ||
| 209 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1Poll | ||
| 210 | (JNIEnv *, jclass, jobject); | ||
| 211 | |||
| 212 | /* | ||
| 213 | * Class: jportmidi_JPortMidiApi | ||
| 214 | * Method: Pm_Write | ||
| 215 | * Signature: (Ljportmidi/JPortMidiApi/PortMidiStream;Ljportmidi/JPortMidiApi/PmEvent;)I | ||
| 216 | */ | ||
| 217 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1Write | ||
| 218 | (JNIEnv *, jclass, jobject, jobject); | ||
| 219 | |||
| 220 | /* | ||
| 221 | * Class: jportmidi_JPortMidiApi | ||
| 222 | * Method: Pm_WriteShort | ||
| 223 | * Signature: (Ljportmidi/JPortMidiApi/PortMidiStream;II)I | ||
| 224 | */ | ||
| 225 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1WriteShort | ||
| 226 | (JNIEnv *, jclass, jobject, jint, jint); | ||
| 227 | |||
| 228 | /* | ||
| 229 | * Class: jportmidi_JPortMidiApi | ||
| 230 | * Method: Pm_WriteSysEx | ||
| 231 | * Signature: (Ljportmidi/JPortMidiApi/PortMidiStream;I[B)I | ||
| 232 | */ | ||
| 233 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1WriteSysEx | ||
| 234 | (JNIEnv *, jclass, jobject, jint, jbyteArray); | ||
| 235 | |||
| 236 | /* | ||
| 237 | * Class: jportmidi_JPortMidiApi | ||
| 238 | * Method: Pt_TimeStart | ||
| 239 | * Signature: (I)I | ||
| 240 | */ | ||
| 241 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pt_1TimeStart | ||
| 242 | (JNIEnv *, jclass, jint); | ||
| 243 | |||
| 244 | /* | ||
| 245 | * Class: jportmidi_JPortMidiApi | ||
| 246 | * Method: Pt_TimeStop | ||
| 247 | * Signature: ()I | ||
| 248 | */ | ||
| 249 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pt_1TimeStop | ||
| 250 | (JNIEnv *, jclass); | ||
| 251 | |||
| 252 | /* | ||
| 253 | * Class: jportmidi_JPortMidiApi | ||
| 254 | * Method: Pt_Time | ||
| 255 | * Signature: ()I | ||
| 256 | */ | ||
| 257 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pt_1Time | ||
| 258 | (JNIEnv *, jclass); | ||
| 259 | |||
| 260 | /* | ||
| 261 | * Class: jportmidi_JPortMidiApi | ||
| 262 | * Method: Pt_TimeStarted | ||
| 263 | * Signature: ()Z | ||
| 264 | */ | ||
| 265 | JNIEXPORT jboolean JNICALL Java_jportmidi_JPortMidiApi_Pt_1TimeStarted | ||
| 266 | (JNIEnv *, jclass); | ||
| 267 | |||
| 268 | #ifdef __cplusplus | ||
| 269 | } | ||
| 270 | #endif | ||
| 271 | #endif | ||
| 272 | /* Header for class jportmidi_JPortMidiApi_PmEvent */ | ||
| 273 | |||
| 274 | #ifndef _Included_jportmidi_JPortMidiApi_PmEvent | ||
| 275 | #define _Included_jportmidi_JPortMidiApi_PmEvent | ||
| 276 | #ifdef __cplusplus | ||
| 277 | extern "C" { | ||
| 278 | #endif | ||
| 279 | #ifdef __cplusplus | ||
| 280 | } | ||
| 281 | #endif | ||
| 282 | #endif | ||
| 283 | /* Header for class jportmidi_JPortMidiApi_PortMidiStream */ | ||
| 284 | |||
| 285 | #ifndef _Included_jportmidi_JPortMidiApi_PortMidiStream | ||
| 286 | #define _Included_jportmidi_JPortMidiApi_PortMidiStream | ||
| 287 | #ifdef __cplusplus | ||
| 288 | extern "C" { | ||
| 289 | #endif | ||
| 290 | #ifdef __cplusplus | ||
| 291 | } | ||
| 292 | #endif | ||
| 293 | #endif | ||
diff --git a/portmidi/pm_java/pmjni/pmjni.c b/portmidi/pm_java/pmjni/pmjni.c new file mode 100644 index 0000000..c60cffb --- /dev/null +++ b/portmidi/pm_java/pmjni/pmjni.c | |||
| @@ -0,0 +1,354 @@ | |||
| 1 | #include "portmidi.h" | ||
| 2 | #include "porttime.h" | ||
| 3 | #include "jportmidi_JportMidiApi.h" | ||
| 4 | #include <stdio.h> | ||
| 5 | |||
| 6 | // these macros assume JNIEnv *env is declared and valid: | ||
| 7 | // | ||
| 8 | #define CLASS(c, obj) jclass c = (*env)->GetObjectClass(env, obj) | ||
| 9 | #define ADDRESS_FID(fid, c) \ | ||
| 10 | jfieldID fid = (*env)->GetFieldID(env, c, "address", "J") | ||
| 11 | // Uses Java Long (64-bit) to make sure there is room to store a | ||
| 12 | // pointer. Cast this to a C long (either 32 or 64 bit) to match | ||
| 13 | // the size of a pointer. Finally cast int to pointer. All this | ||
| 14 | // is supposed to avoid C compiler warnings and (worse) losing | ||
| 15 | // address bits. | ||
| 16 | #define PMSTREAM(obj, fid) ((PmStream *) (intptr_t) (*env)->GetLongField(env, obj, fid)) | ||
| 17 | // Cast stream to long to convert integer to pointer, then expand | ||
| 18 | // integer to 64-bit jlong. This avoids compiler warnings. | ||
| 19 | #define SET_PMSTREAM(obj, fid, stream) \ | ||
| 20 | (*env)->SetLongField(env, obj, fid, (jlong) (intptr_t) stream) | ||
| 21 | |||
| 22 | |||
| 23 | /* | ||
| 24 | * Method: Pm_Initialize | ||
| 25 | */ | ||
| 26 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1Initialize | ||
| 27 | (JNIEnv *env, jclass cl) | ||
| 28 | { | ||
| 29 | return Pm_Initialize(); | ||
| 30 | } | ||
| 31 | |||
| 32 | |||
| 33 | /* | ||
| 34 | * Method: Pm_Terminate | ||
| 35 | */ | ||
| 36 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1Terminate | ||
| 37 | (JNIEnv *env, jclass cl) | ||
| 38 | { | ||
| 39 | return Pm_Terminate(); | ||
| 40 | } | ||
| 41 | |||
| 42 | |||
| 43 | /* | ||
| 44 | * Method: Pm_HasHostError | ||
| 45 | */ | ||
| 46 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1HasHostError | ||
| 47 | (JNIEnv *env, jclass cl, jobject jstream) | ||
| 48 | { | ||
| 49 | CLASS(c, jstream); | ||
| 50 | ADDRESS_FID(fid, c); | ||
| 51 | return Pm_HasHostError(PMSTREAM(jstream, fid)); | ||
| 52 | } | ||
| 53 | |||
| 54 | |||
| 55 | /* | ||
| 56 | * Method: Pm_GetErrorText | ||
| 57 | */ | ||
| 58 | JNIEXPORT jstring JNICALL Java_jportmidi_JPortMidiApi_Pm_1GetErrorText | ||
| 59 | (JNIEnv *env, jclass cl, jint i) | ||
| 60 | { | ||
| 61 | return (*env)->NewStringUTF(env, Pm_GetErrorText(i)); | ||
| 62 | } | ||
| 63 | |||
| 64 | |||
| 65 | /* | ||
| 66 | * Method: Pm_GetHostErrorText | ||
| 67 | */ | ||
| 68 | JNIEXPORT jstring JNICALL Java_jportmidi_JPortMidiApi_Pm_1GetHostErrorText | ||
| 69 | (JNIEnv *env, jclass cl) | ||
| 70 | { | ||
| 71 | char msg[PM_HOST_ERROR_MSG_LEN]; | ||
| 72 | Pm_GetHostErrorText(msg, PM_HOST_ERROR_MSG_LEN); | ||
| 73 | return (*env)->NewStringUTF(env, msg); | ||
| 74 | } | ||
| 75 | |||
| 76 | |||
| 77 | /* | ||
| 78 | * Method: Pm_CountDevices | ||
| 79 | */ | ||
| 80 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1CountDevices | ||
| 81 | (JNIEnv *env, jclass cl) | ||
| 82 | { | ||
| 83 | return Pm_CountDevices(); | ||
| 84 | } | ||
| 85 | |||
| 86 | |||
| 87 | /* | ||
| 88 | * Method: Pm_GetDefaultInputDeviceID | ||
| 89 | */ | ||
| 90 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1GetDefaultInputDeviceID | ||
| 91 | (JNIEnv *env, jclass cl) | ||
| 92 | { | ||
| 93 | return Pm_GetDefaultInputDeviceID(); | ||
| 94 | } | ||
| 95 | |||
| 96 | |||
| 97 | /* | ||
| 98 | * Method: Pm_GetDefaultOutputDeviceID | ||
| 99 | */ | ||
| 100 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1GetDefaultOutputDeviceID | ||
| 101 | (JNIEnv *env, jclass cl) | ||
| 102 | { | ||
| 103 | return Pm_GetDefaultOutputDeviceID(); | ||
| 104 | } | ||
| 105 | |||
| 106 | |||
| 107 | /* | ||
| 108 | * Method: Pm_GetDeviceInterf | ||
| 109 | */ | ||
| 110 | JNIEXPORT jstring JNICALL Java_jportmidi_JPortMidiApi_Pm_1GetDeviceInterf | ||
| 111 | (JNIEnv *env, jclass cl, jint i) | ||
| 112 | { | ||
| 113 | const PmDeviceInfo *info = Pm_GetDeviceInfo(i); | ||
| 114 | if (!info) return NULL; | ||
| 115 | return (*env)->NewStringUTF(env, info->interf); | ||
| 116 | } | ||
| 117 | |||
| 118 | |||
| 119 | /* | ||
| 120 | * Method: Pm_GetDeviceName | ||
| 121 | */ | ||
| 122 | JNIEXPORT jstring JNICALL Java_jportmidi_JPortMidiApi_Pm_1GetDeviceName | ||
| 123 | (JNIEnv *env, jclass cl, jint i) | ||
| 124 | { | ||
| 125 | const PmDeviceInfo *info = Pm_GetDeviceInfo(i); | ||
| 126 | if (!info) return NULL; | ||
| 127 | return (*env)->NewStringUTF(env, info->name); | ||
| 128 | } | ||
| 129 | |||
| 130 | |||
| 131 | /* | ||
| 132 | * Method: Pm_GetDeviceInput | ||
| 133 | */ | ||
| 134 | JNIEXPORT jboolean JNICALL Java_jportmidi_JPortMidiApi_Pm_1GetDeviceInput | ||
| 135 | (JNIEnv *env, jclass cl, jint i) | ||
| 136 | { | ||
| 137 | const PmDeviceInfo *info = Pm_GetDeviceInfo(i); | ||
| 138 | if (!info) return (jboolean) 0; | ||
| 139 | return (jboolean) info->input; | ||
| 140 | } | ||
| 141 | |||
| 142 | |||
| 143 | /* | ||
| 144 | * Method: Pm_GetDeviceOutput | ||
| 145 | */ | ||
| 146 | JNIEXPORT jboolean JNICALL Java_jportmidi_JPortMidiApi_Pm_1GetDeviceOutput | ||
| 147 | (JNIEnv *env, jclass cl, jint i) | ||
| 148 | { | ||
| 149 | const PmDeviceInfo *info = Pm_GetDeviceInfo(i); | ||
| 150 | if (!info) return (jboolean) 0; | ||
| 151 | return (jboolean) info->output; | ||
| 152 | } | ||
| 153 | |||
| 154 | |||
| 155 | /* | ||
| 156 | * Method: Pm_OpenInput | ||
| 157 | */ | ||
| 158 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1OpenInput | ||
| 159 | (JNIEnv *env, jclass cl, | ||
| 160 | jobject jstream, jint index, jstring extras, jint bufsiz) | ||
| 161 | { | ||
| 162 | PmError rslt; | ||
| 163 | PortMidiStream *stream; | ||
| 164 | CLASS(c, jstream); | ||
| 165 | ADDRESS_FID(fid, c); | ||
| 166 | rslt = Pm_OpenInput(&stream, index, NULL, bufsiz, NULL, NULL); | ||
| 167 | SET_PMSTREAM(jstream, fid, stream); | ||
| 168 | return rslt; | ||
| 169 | } | ||
| 170 | |||
| 171 | |||
| 172 | /* | ||
| 173 | * Method: Pm_OpenOutput | ||
| 174 | */ | ||
| 175 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1OpenOutput | ||
| 176 | (JNIEnv *env, jclass cl, jobject jstream, jint index, jstring extras, | ||
| 177 | jint bufsiz, jint latency) | ||
| 178 | { | ||
| 179 | PmError rslt; | ||
| 180 | PortMidiStream *stream; | ||
| 181 | CLASS(c, jstream); | ||
| 182 | ADDRESS_FID(fid, c); | ||
| 183 | rslt = Pm_OpenOutput(&stream, index, NULL, bufsiz, NULL, NULL, latency); | ||
| 184 | SET_PMSTREAM(jstream, fid, stream); | ||
| 185 | return rslt; | ||
| 186 | } | ||
| 187 | |||
| 188 | |||
| 189 | /* | ||
| 190 | * Method: Pm_SetFilter | ||
| 191 | */ | ||
| 192 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1SetFilter | ||
| 193 | (JNIEnv *env, jclass cl, jobject jstream, jint filters) | ||
| 194 | { | ||
| 195 | CLASS(c, jstream); | ||
| 196 | ADDRESS_FID(fid, c); | ||
| 197 | return Pm_SetFilter(PMSTREAM(jstream, fid), filters); | ||
| 198 | } | ||
| 199 | |||
| 200 | |||
| 201 | /* | ||
| 202 | * Method: Pm_SetChannelMask | ||
| 203 | */ | ||
| 204 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1SetChannelMask | ||
| 205 | (JNIEnv *env, jclass cl, jobject jstream, jint mask) | ||
| 206 | { | ||
| 207 | CLASS(c, jstream); | ||
| 208 | ADDRESS_FID(fid, c); | ||
| 209 | return Pm_SetChannelMask(PMSTREAM(jstream, fid), mask); | ||
| 210 | } | ||
| 211 | |||
| 212 | |||
| 213 | /* | ||
| 214 | * Method: Pm_Abort | ||
| 215 | */ | ||
| 216 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1Abort | ||
| 217 | (JNIEnv *env, jclass cl, jobject jstream) | ||
| 218 | { | ||
| 219 | CLASS(c, jstream); | ||
| 220 | ADDRESS_FID(fid, c); | ||
| 221 | return Pm_Abort(PMSTREAM(jstream, fid)); | ||
| 222 | } | ||
| 223 | |||
| 224 | |||
| 225 | /* | ||
| 226 | * Method: Pm_Close | ||
| 227 | */ | ||
| 228 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1Close | ||
| 229 | (JNIEnv *env, jclass cl, jobject jstream) | ||
| 230 | { | ||
| 231 | CLASS(c, jstream); | ||
| 232 | ADDRESS_FID(fid, c); | ||
| 233 | return Pm_Close(PMSTREAM(jstream, fid)); | ||
| 234 | } | ||
| 235 | |||
| 236 | |||
| 237 | /* | ||
| 238 | * Method: Pm_Read | ||
| 239 | */ | ||
| 240 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1Read | ||
| 241 | (JNIEnv *env, jclass cl, jobject jstream, jobject jpmevent) | ||
| 242 | { | ||
| 243 | CLASS(jstream_class, jstream); | ||
| 244 | ADDRESS_FID(address_fid, jstream_class); | ||
| 245 | jclass jpmevent_class = (*env)->GetObjectClass(env, jpmevent); | ||
| 246 | jfieldID message_fid = | ||
| 247 | (*env)->GetFieldID(env, jpmevent_class, "message", "I"); | ||
| 248 | jfieldID timestamp_fid = | ||
| 249 | (*env)->GetFieldID(env, jpmevent_class, "timestamp", "I"); | ||
| 250 | PmEvent buffer; | ||
| 251 | PmError rslt = Pm_Read(PMSTREAM(jstream, address_fid), &buffer, 1); | ||
| 252 | (*env)->SetIntField(env, jpmevent, message_fid, buffer.message); | ||
| 253 | (*env)->SetIntField(env, jpmevent, timestamp_fid, buffer.timestamp); | ||
| 254 | return rslt; | ||
| 255 | } | ||
| 256 | |||
| 257 | |||
| 258 | /* | ||
| 259 | * Method: Pm_Poll | ||
| 260 | */ | ||
| 261 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1Poll | ||
| 262 | (JNIEnv *env, jclass cl, jobject jstream) | ||
| 263 | { | ||
| 264 | CLASS(c, jstream); | ||
| 265 | ADDRESS_FID(fid, c); | ||
| 266 | return Pm_Poll(PMSTREAM(jstream, fid)); | ||
| 267 | } | ||
| 268 | |||
| 269 | |||
| 270 | /* | ||
| 271 | * Method: Pm_Write | ||
| 272 | */ | ||
| 273 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1Write | ||
| 274 | (JNIEnv *env, jclass cl, jobject jstream, jobject jpmevent) | ||
| 275 | { | ||
| 276 | CLASS(jstream_class, jstream); | ||
| 277 | ADDRESS_FID(address_fid, jstream_class); | ||
| 278 | jclass jpmevent_class = (*env)->GetObjectClass(env, jpmevent); | ||
| 279 | jfieldID message_fid = | ||
| 280 | (*env)->GetFieldID(env, jpmevent_class, "message", "I"); | ||
| 281 | jfieldID timestamp_fid = | ||
| 282 | (*env)->GetFieldID(env, jpmevent_class, "timestamp", "I"); | ||
| 283 | // note that we call WriteShort because it's simpler than constructing | ||
| 284 | // a buffer and passing it to Pm_Write | ||
| 285 | return Pm_WriteShort(PMSTREAM(jstream, address_fid), | ||
| 286 | (*env)->GetIntField(env, jpmevent, timestamp_fid), | ||
| 287 | (*env)->GetIntField(env, jpmevent, message_fid)); | ||
| 288 | } | ||
| 289 | |||
| 290 | |||
| 291 | /* | ||
| 292 | * Method: Pm_WriteShort | ||
| 293 | */ | ||
| 294 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1WriteShort | ||
| 295 | (JNIEnv *env, jclass cl, jobject jstream, jint when, jint msg) | ||
| 296 | { | ||
| 297 | CLASS(c, jstream); | ||
| 298 | ADDRESS_FID(fid, c); | ||
| 299 | return Pm_WriteShort(PMSTREAM(jstream, fid), when, msg); | ||
| 300 | } | ||
| 301 | |||
| 302 | |||
| 303 | /* | ||
| 304 | * Method: Pm_WriteSysEx | ||
| 305 | */ | ||
| 306 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1WriteSysEx | ||
| 307 | (JNIEnv *env, jclass cl, jobject jstream, jint when, jbyteArray jmsg) | ||
| 308 | { | ||
| 309 | CLASS(c, jstream); | ||
| 310 | ADDRESS_FID(fid, c); | ||
| 311 | jbyte *bytes = (*env)->GetByteArrayElements(env, jmsg, 0); | ||
| 312 | PmError rslt = Pm_WriteSysEx(PMSTREAM(jstream, fid), when, | ||
| 313 | (unsigned char *) bytes); | ||
| 314 | (*env)->ReleaseByteArrayElements(env, jmsg, bytes, 0); | ||
| 315 | return rslt; | ||
| 316 | } | ||
| 317 | |||
| 318 | /* | ||
| 319 | * Method: Pt_TimeStart | ||
| 320 | */ | ||
| 321 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pt_1TimeStart | ||
| 322 | (JNIEnv *env, jclass c, jint resolution) | ||
| 323 | { | ||
| 324 | return Pt_Start(resolution, NULL, NULL); | ||
| 325 | } | ||
| 326 | |||
| 327 | /* | ||
| 328 | * Method: Pt_TimeStop | ||
| 329 | */ | ||
| 330 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pt_1TimeStop | ||
| 331 | (JNIEnv *env, jclass c) | ||
| 332 | { | ||
| 333 | return Pt_Stop(); | ||
| 334 | } | ||
| 335 | |||
| 336 | /* | ||
| 337 | * Method: Pt_Time | ||
| 338 | */ | ||
| 339 | JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pt_1Time | ||
| 340 | (JNIEnv *env, jclass c) | ||
| 341 | { | ||
| 342 | return Pt_Time(); | ||
| 343 | } | ||
| 344 | |||
| 345 | /* | ||
| 346 | * Method: Pt_TimeStarted | ||
| 347 | */ | ||
| 348 | JNIEXPORT jboolean JNICALL Java_jportmidi_JPortMidiApi_Pt_1TimeStarted | ||
| 349 | (JNIEnv *env, jclass c) | ||
| 350 | { | ||
| 351 | return Pt_Started(); | ||
| 352 | } | ||
| 353 | |||
| 354 | |||
diff --git a/portmidi/pm_java/pmjni/pmjni.rc b/portmidi/pm_java/pmjni/pmjni.rc new file mode 100644 index 0000000..1b7522b --- /dev/null +++ b/portmidi/pm_java/pmjni/pmjni.rc | |||
| @@ -0,0 +1,63 @@ | |||
| 1 | // Microsoft Visual C++ generated resource script. | ||
| 2 | // | ||
| 3 | #include "resource.h" | ||
| 4 | |||
| 5 | #define APSTUDIO_READONLY_SYMBOLS | ||
| 6 | ///////////////////////////////////////////////////////////////////////////// | ||
| 7 | // | ||
| 8 | // Generated from the TEXTINCLUDE 2 resource. | ||
| 9 | // | ||
| 10 | #include "afxres.h" | ||
| 11 | |||
| 12 | ///////////////////////////////////////////////////////////////////////////// | ||
| 13 | #undef APSTUDIO_READONLY_SYMBOLS | ||
| 14 | |||
| 15 | ///////////////////////////////////////////////////////////////////////////// | ||
| 16 | // English (U.S.) resources | ||
| 17 | |||
| 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) | ||
| 19 | #ifdef _WIN32 | ||
| 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US | ||
| 21 | #pragma code_page(1252) | ||
| 22 | #endif //_WIN32 | ||
| 23 | |||
| 24 | #ifdef APSTUDIO_INVOKED | ||
| 25 | ///////////////////////////////////////////////////////////////////////////// | ||
| 26 | // | ||
| 27 | // TEXTINCLUDE | ||
| 28 | // | ||
| 29 | |||
| 30 | 1 TEXTINCLUDE | ||
| 31 | BEGIN | ||
| 32 | "resource.h\0" | ||
| 33 | END | ||
| 34 | |||
| 35 | 2 TEXTINCLUDE | ||
| 36 | BEGIN | ||
| 37 | "#include ""afxres.h""\r\n" | ||
| 38 | "\0" | ||
| 39 | END | ||
| 40 | |||
| 41 | 3 TEXTINCLUDE | ||
| 42 | BEGIN | ||
| 43 | "\r\n" | ||
| 44 | "\0" | ||
| 45 | END | ||
| 46 | |||
| 47 | #endif // APSTUDIO_INVOKED | ||
| 48 | |||
| 49 | #endif // English (U.S.) resources | ||
| 50 | ///////////////////////////////////////////////////////////////////////////// | ||
| 51 | |||
| 52 | |||
| 53 | |||
| 54 | #ifndef APSTUDIO_INVOKED | ||
| 55 | ///////////////////////////////////////////////////////////////////////////// | ||
| 56 | // | ||
| 57 | // Generated from the TEXTINCLUDE 3 resource. | ||
| 58 | // | ||
| 59 | |||
| 60 | |||
| 61 | ///////////////////////////////////////////////////////////////////////////// | ||
| 62 | #endif // not APSTUDIO_INVOKED | ||
| 63 | |||
