00001
00017 #include "CoreMidiInputPort.h"
00018
00020
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 void MIDIInput(const MIDIPacketList *packets, void *readProcRefCon, void *srcConnRefCon) {
00033
00034 static mach_timebase_info_data_t sTimebaseInfo;
00035 JNIEnv *env;
00036
00037
00038
00039
00040
00041 if ( sTimebaseInfo.denom == 0 ) {
00042
00043 (void) mach_timebase_info(&sTimebaseInfo);
00044
00045 }
00046
00047
00048 MIDI_CALLBACK_PARAMETERS *callbackParameters = (MIDI_CALLBACK_PARAMETERS *) srcConnRefCon;
00049
00050
00051 int getEnvStat = callbackParameters->jvm->GetEnv((void **) &env, NULL);
00052
00053
00054 if ( getEnvStat == JNI_EDETACHED ) {
00055
00056 if ( callbackParameters->jvm->AttachCurrentThread((void **) &env, NULL) != 0) {
00057
00058 std::cout << "Failed to attach" << std::endl;
00059 ThrowException(env,CFSTR("MIDIInput - Failed to attach"),-1);
00060
00061 }
00062
00063 } else if ( getEnvStat == JNI_EVERSION ) {
00064
00065 std::cout << "GetEnv: version not supported" << std::endl;
00066 ThrowException(env,CFSTR("MIDIInput - GetEnv: version not supported"),-1);
00067
00068 }
00069
00070
00071 MIDIPacket *packet = (MIDIPacket *) &packets->packet[0];
00072
00073 for ( int i = 0; i < packets->numPackets; i += 1 ) {
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 uint64_t timestamp = (packet->timeStamp == 0) ? 0 : (packet->timeStamp / 1000) * sTimebaseInfo.numer / sTimebaseInfo.denom;
00089
00090
00091 jbyteArray array = env->NewByteArray(packet->length);
00092 env->SetByteArrayRegion(array, 0, packet->length, (jbyte*) packet->data);
00093
00094
00095 env->CallVoidMethod(callbackParameters->object, callbackParameters->methodID, timestamp, packet->length, array);
00096
00097
00098 env->ReleaseByteArrayElements(array, NULL, JNI_ABORT);
00099
00100
00101 if ( env->ExceptionCheck() ) {
00102
00103 env->ExceptionDescribe();
00104
00105 }
00106
00107
00108 packet = MIDIPacketNext(packet);
00109
00110 }
00111
00112
00113 callbackParameters->jvm->DetachCurrentThread();
00114
00115 }
00116
00118
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 JNIEXPORT jint JNICALL Java_uk_co_xfactorylibrarians_coremidi4j_CoreMidiInputPort_createInputPort(JNIEnv *env, jobject obj, jint clientReference, jstring portName) {
00140
00141 MIDIPortRef inputPort;
00142 OSStatus status;
00143
00144
00145 const char *portNameString = env->GetStringUTFChars(portName,0);
00146 CFStringRef cfPortName = CFStringCreateWithCString(NULL,portNameString,kCFStringEncodingMacRoman);
00147
00148
00149 status = MIDIInputPortCreate(clientReference, cfPortName, MIDIInput, NULL, &inputPort);
00150
00151
00152 env->ReleaseStringUTFChars(portName, portNameString);
00153
00154
00155 if ( status != 0) {
00156
00157 ThrowException(env,CFSTR("MIDIInputPortCreate"),status);
00158
00159 }
00160
00161
00162 return inputPort;
00163
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 JNIEXPORT jlong JNICALL Java_uk_co_xfactorylibrarians_coremidi4j_CoreMidiInputPort_midiPortConnectSource(JNIEnv *env, jobject obj, jint inputPortReference, jobject sourceDevice) {
00183
00184 OSStatus status;
00185
00186
00187 MIDI_CALLBACK_PARAMETERS *callbackParameters = (MIDI_CALLBACK_PARAMETERS *) malloc(sizeof(MIDI_CALLBACK_PARAMETERS));
00188
00189
00190 if ( callbackParameters == NULL ) {
00191
00192 ThrowException(env,CFSTR("MIDIPortConnectSource"),-1);
00193
00194 }
00195
00196
00197 callbackParameters->object = env->NewGlobalRef(sourceDevice);
00198 callbackParameters->methodID = env->GetMethodID(env->GetObjectClass(sourceDevice), "messageCallback", "(JI[B)V");
00199 jint result = env->GetJavaVM(&callbackParameters->jvm);
00200
00201
00202 assert (result == JNI_OK);
00203
00204
00205 jobject info = env->GetObjectField(sourceDevice, env->GetFieldID(env->GetObjectClass(sourceDevice), "info","Luk/co/xfactorylibrarians/coremidi4j/CoreMidiDeviceInfo;"));
00206
00207
00208 int sourceEndPointReference = env->GetIntField(info, env->GetFieldID(env->GetObjectClass(info),"endPointReference","I"));
00209
00210
00211 status = MIDIPortConnectSource(inputPortReference, sourceEndPointReference, callbackParameters);
00212
00213
00214 if ( status != 0) {
00215
00216 ThrowException(env,CFSTR("MIDIPortConnectSource"),status);
00217
00218 }
00219
00220
00221 return (jlong) callbackParameters;
00222
00223 }
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 JNIEXPORT void JNICALL Java_uk_co_xfactorylibrarians_coremidi4j_CoreMidiInputPort_midiPortDisconnectSource(JNIEnv *env, jobject obj, jint inputPortReference, jlong memoryReference, jobject sourceDevice) {
00243
00244 OSStatus status;
00245
00246
00247 jobject info = env->GetObjectField(sourceDevice, env->GetFieldID(env->GetObjectClass(sourceDevice), "info","Luk/co/xfactorylibrarians/coremidi4j/CoreMidiDeviceInfo;"));
00248
00249
00250 int sourceEndPointReference = env->GetIntField(info, env->GetFieldID(env->GetObjectClass(info),"endPointReference","I"));
00251
00252
00253 status = MIDIPortDisconnectSource(inputPortReference, sourceEndPointReference);
00254
00255
00256 env->DeleteGlobalRef(((MIDI_CALLBACK_PARAMETERS *) memoryReference)->object);
00257
00258
00259
00260
00261 free((void *) memoryReference);
00262
00263
00264 if ( status != 0) {
00265
00266 ThrowException(env,CFSTR("MIDIPortDisconnectSource"),status);
00267
00268 }
00269
00270 }