pmjni.c (8784B)
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 *) (long) (*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) (long) 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