mirror of
				https://github.com/cookiengineer/audacity
				synced 2025-10-30 17:23:51 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			355 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			355 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include "portmidi.h"
 | |
| #include "porttime.h"
 | |
| #include "jportmidi_JportMidiApi.h"
 | |
| #include <stdio.h>
 | |
| 
 | |
| // these macros assume JNIEnv *env is declared and valid:
 | |
| //
 | |
| #define CLASS(c, obj) jclass c = (*env)->GetObjectClass(env, obj)
 | |
| #define ADDRESS_FID(fid, c) \
 | |
|     jfieldID fid = (*env)->GetFieldID(env, c, "address", "J")
 | |
| // Uses Java Long (64-bit) to make sure there is room to store a 
 | |
| // pointer. Cast this to a C long (either 32 or 64 bit) to match
 | |
| // the size of a pointer. Finally cast int to pointer. All this
 | |
| // is supposed to avoid C compiler warnings and (worse) losing
 | |
| // address bits.
 | |
| #define PMSTREAM(obj, fid) ((PmStream *) (long) (*env)->GetLongField(env, obj, fid))
 | |
| // Cast stream to long to convert integer to pointer, then expand
 | |
| // integer to 64-bit jlong. This avoids compiler warnings.
 | |
| #define SET_PMSTREAM(obj, fid, stream) \
 | |
|     (*env)->SetLongField(env, obj, fid, (jlong) (long) stream)
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Method:    Pm_Initialize
 | |
|  */
 | |
| JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1Initialize
 | |
|   (JNIEnv *env, jclass cl)
 | |
| {
 | |
|     return Pm_Initialize();
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Method:    Pm_Terminate
 | |
|  */
 | |
| JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1Terminate
 | |
|   (JNIEnv *env, jclass cl)
 | |
| {
 | |
|     return Pm_Terminate();
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Method:    Pm_HasHostError
 | |
|  */
 | |
| JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1HasHostError
 | |
|   (JNIEnv *env, jclass cl, jobject jstream)
 | |
| {
 | |
|     CLASS(c, jstream);
 | |
|     ADDRESS_FID(fid, c);
 | |
|     return Pm_HasHostError(PMSTREAM(jstream, fid));
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Method:    Pm_GetErrorText
 | |
|  */
 | |
| JNIEXPORT jstring JNICALL Java_jportmidi_JPortMidiApi_Pm_1GetErrorText
 | |
|   (JNIEnv *env, jclass cl, jint i)
 | |
| {
 | |
|     return (*env)->NewStringUTF(env, Pm_GetErrorText(i));
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Method:    Pm_GetHostErrorText
 | |
|  */
 | |
| JNIEXPORT jstring JNICALL Java_jportmidi_JPortMidiApi_Pm_1GetHostErrorText
 | |
|   (JNIEnv *env, jclass cl)
 | |
| {
 | |
|     char msg[PM_HOST_ERROR_MSG_LEN];
 | |
|     Pm_GetHostErrorText(msg, PM_HOST_ERROR_MSG_LEN);
 | |
|     return (*env)->NewStringUTF(env, msg);
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Method:    Pm_CountDevices
 | |
|  */
 | |
| JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1CountDevices
 | |
|   (JNIEnv *env, jclass cl)
 | |
| {
 | |
|     return Pm_CountDevices();
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Method:    Pm_GetDefaultInputDeviceID
 | |
|  */
 | |
| JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1GetDefaultInputDeviceID
 | |
|   (JNIEnv *env, jclass cl)
 | |
| {
 | |
|     return Pm_GetDefaultInputDeviceID();
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Method:    Pm_GetDefaultOutputDeviceID
 | |
|  */
 | |
| JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1GetDefaultOutputDeviceID
 | |
|   (JNIEnv *env, jclass cl)
 | |
| {
 | |
|     return Pm_GetDefaultOutputDeviceID();
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Method:    Pm_GetDeviceInterf
 | |
|  */
 | |
| JNIEXPORT jstring JNICALL Java_jportmidi_JPortMidiApi_Pm_1GetDeviceInterf
 | |
|   (JNIEnv *env, jclass cl, jint i)
 | |
| {
 | |
|     const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
 | |
|     if (!info) return NULL;
 | |
|     return (*env)->NewStringUTF(env, info->interf);
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Method:    Pm_GetDeviceName
 | |
|  */
 | |
| JNIEXPORT jstring JNICALL Java_jportmidi_JPortMidiApi_Pm_1GetDeviceName
 | |
|   (JNIEnv *env, jclass cl, jint i)
 | |
| {
 | |
|     const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
 | |
|     if (!info) return NULL;
 | |
|     return (*env)->NewStringUTF(env, info->name);
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Method:    Pm_GetDeviceInput
 | |
|  */
 | |
| JNIEXPORT jboolean JNICALL Java_jportmidi_JPortMidiApi_Pm_1GetDeviceInput
 | |
|   (JNIEnv *env, jclass cl, jint i)
 | |
| {
 | |
|     const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
 | |
|     if (!info) return (jboolean) 0;
 | |
|     return (jboolean) info->input;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Method:    Pm_GetDeviceOutput
 | |
|  */
 | |
| JNIEXPORT jboolean JNICALL Java_jportmidi_JPortMidiApi_Pm_1GetDeviceOutput
 | |
|   (JNIEnv *env, jclass cl, jint i)
 | |
| {
 | |
|     const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
 | |
|     if (!info) return (jboolean) 0;
 | |
|     return (jboolean) info->output;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Method:    Pm_OpenInput
 | |
|  */
 | |
| JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1OpenInput
 | |
|   (JNIEnv *env, jclass cl, 
 | |
|    jobject jstream, jint index, jstring extras, jint bufsiz)
 | |
| {
 | |
|     PmError rslt;
 | |
|     PortMidiStream *stream;
 | |
|     CLASS(c, jstream);
 | |
|     ADDRESS_FID(fid, c);
 | |
|     rslt = Pm_OpenInput(&stream, index, NULL, bufsiz, NULL, NULL);
 | |
|     SET_PMSTREAM(jstream, fid, stream);
 | |
|     return rslt;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Method:    Pm_OpenOutput
 | |
|  */
 | |
| JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1OpenOutput
 | |
|   (JNIEnv *env, jclass cl, jobject jstream, jint index, jstring extras,
 | |
|    jint bufsiz, jint latency)
 | |
| {
 | |
|     PmError rslt;
 | |
|     PortMidiStream *stream;
 | |
|     CLASS(c, jstream);
 | |
|     ADDRESS_FID(fid, c);
 | |
|     rslt = Pm_OpenOutput(&stream, index, NULL, bufsiz, NULL, NULL, latency);
 | |
|     SET_PMSTREAM(jstream, fid, stream);
 | |
|     return rslt;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Method:    Pm_SetFilter
 | |
|  */
 | |
| JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1SetFilter
 | |
|   (JNIEnv *env, jclass cl, jobject jstream, jint filters)
 | |
| {
 | |
|     CLASS(c, jstream);
 | |
|     ADDRESS_FID(fid, c);
 | |
|     return Pm_SetFilter(PMSTREAM(jstream, fid), filters);
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Method:    Pm_SetChannelMask
 | |
|  */
 | |
| JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1SetChannelMask
 | |
|   (JNIEnv *env, jclass cl, jobject jstream, jint mask)
 | |
| {
 | |
|     CLASS(c, jstream);
 | |
|     ADDRESS_FID(fid, c);
 | |
|     return Pm_SetChannelMask(PMSTREAM(jstream, fid), mask);
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Method:    Pm_Abort
 | |
|  */
 | |
| JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1Abort
 | |
|   (JNIEnv *env, jclass cl, jobject jstream)
 | |
| {
 | |
|     CLASS(c, jstream);
 | |
|     ADDRESS_FID(fid, c);
 | |
|     return Pm_Abort(PMSTREAM(jstream, fid));
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Method:    Pm_Close
 | |
|  */
 | |
| JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1Close
 | |
|   (JNIEnv *env, jclass cl, jobject jstream)
 | |
| {
 | |
|     CLASS(c, jstream);
 | |
|     ADDRESS_FID(fid, c);
 | |
|     return Pm_Close(PMSTREAM(jstream, fid));
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Method:    Pm_Read
 | |
|  */
 | |
| JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1Read
 | |
|   (JNIEnv *env, jclass cl, jobject jstream, jobject jpmevent)
 | |
| {
 | |
|     CLASS(jstream_class, jstream);
 | |
|     ADDRESS_FID(address_fid, jstream_class);
 | |
|     jclass jpmevent_class = (*env)->GetObjectClass(env, jpmevent);
 | |
|     jfieldID message_fid = 
 | |
|             (*env)->GetFieldID(env, jpmevent_class, "message", "I");
 | |
|     jfieldID timestamp_fid = 
 | |
|             (*env)->GetFieldID(env, jpmevent_class, "timestamp", "I");
 | |
|     PmEvent buffer;
 | |
|     PmError rslt = Pm_Read(PMSTREAM(jstream, address_fid), &buffer, 1);
 | |
|     (*env)->SetIntField(env, jpmevent, message_fid, buffer.message);
 | |
|     (*env)->SetIntField(env, jpmevent, timestamp_fid, buffer.timestamp);
 | |
|     return rslt;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Method:    Pm_Poll
 | |
|  */
 | |
| JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1Poll
 | |
|         (JNIEnv *env, jclass cl, jobject jstream)
 | |
| {
 | |
|     CLASS(c, jstream);
 | |
|     ADDRESS_FID(fid, c);
 | |
|     return Pm_Poll(PMSTREAM(jstream, fid));
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Method:    Pm_Write
 | |
|  */
 | |
| JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1Write
 | |
|         (JNIEnv *env, jclass cl, jobject jstream, jobject jpmevent)
 | |
| {
 | |
|     CLASS(jstream_class, jstream);
 | |
|     ADDRESS_FID(address_fid, jstream_class);
 | |
|     jclass jpmevent_class = (*env)->GetObjectClass(env, jpmevent);
 | |
|     jfieldID message_fid = 
 | |
|             (*env)->GetFieldID(env, jpmevent_class, "message", "I");
 | |
|     jfieldID timestamp_fid = 
 | |
|             (*env)->GetFieldID(env, jpmevent_class, "timestamp", "I");
 | |
|     // note that we call WriteShort because it's simpler than constructing
 | |
|     // a buffer and passing it to Pm_Write
 | |
|     return Pm_WriteShort(PMSTREAM(jstream, address_fid),
 | |
|             (*env)->GetIntField(env, jpmevent, timestamp_fid),
 | |
|             (*env)->GetIntField(env, jpmevent, message_fid));
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Method:    Pm_WriteShort
 | |
|  */
 | |
| JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1WriteShort
 | |
|   (JNIEnv *env, jclass cl, jobject jstream, jint when, jint msg)
 | |
| {
 | |
|     CLASS(c, jstream);
 | |
|     ADDRESS_FID(fid, c);
 | |
|     return Pm_WriteShort(PMSTREAM(jstream, fid), when, msg);
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Method:    Pm_WriteSysEx
 | |
|  */
 | |
| JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1WriteSysEx
 | |
|   (JNIEnv *env, jclass cl, jobject jstream, jint when, jbyteArray jmsg)
 | |
| {
 | |
|     CLASS(c, jstream);
 | |
|     ADDRESS_FID(fid, c);
 | |
|     jbyte *bytes = (*env)->GetByteArrayElements(env, jmsg, 0);
 | |
|     PmError rslt = Pm_WriteSysEx(PMSTREAM(jstream, fid), when, 
 | |
|                                  (unsigned char *) bytes);
 | |
|     (*env)->ReleaseByteArrayElements(env, jmsg, bytes, 0);
 | |
|     return rslt;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Method:    Pt_TimeStart
 | |
|  */
 | |
| JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pt_1TimeStart
 | |
|         (JNIEnv *env, jclass c, jint resolution)
 | |
| {
 | |
|     return Pt_Start(resolution, NULL, NULL);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Method:    Pt_TimeStop
 | |
|  */
 | |
| JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pt_1TimeStop
 | |
|         (JNIEnv *env, jclass c)
 | |
|  {
 | |
|      return Pt_Stop();
 | |
|  }
 | |
| 
 | |
| /*
 | |
|  * Method:    Pt_Time
 | |
|  */
 | |
| JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pt_1Time
 | |
|         (JNIEnv *env, jclass c)
 | |
|  {
 | |
|      return Pt_Time();
 | |
|  }
 | |
| 
 | |
| /*
 | |
|  * Method:    Pt_TimeStarted
 | |
|  */
 | |
| JNIEXPORT jboolean JNICALL Java_jportmidi_JPortMidiApi_Pt_1TimeStarted
 | |
|         (JNIEnv *env, jclass c)
 | |
| {
 | |
|     return Pt_Started();
 | |
| }
 | |
| 
 | |
| 
 |