Re: Calling Java code from an audio or Midi callback (Bill Stewart)
Re: Calling Java code from an audio or Midi callback (Bill Stewart)
- Subject: Re: Calling Java code from an audio or Midi callback (Bill Stewart)
- From: Stephane Letz <email@hidden>
- Date: Tue, 16 Apr 2002 10:30:50 +0200
>
The CAJava code will dispatch into your Java code from the callback in the
>
thread that it is running on.
>
The only overhead incurred in this is the overhead of crossing the context
>
into Java - we use variants of the JNI calls env->CallIntMethodV (I
>
think...)
>
Taking a lock is a "bad idea" in the I/O threads - I you end up waiting
>
you'll miss the I/O cycle.
>
Aside from the special priveleges in terms of runtime scheduling the real
>
time threads are just threads and there's nothing "special" about them, so
>
you can just call your Java code directly...
Thanks.
I changed the method and tried to callback the Java code directly using the
following method:
typedef struct NativeContext {
JNIEnv * fEnv;
jmethodID fMid;
jobject fObj;
jclass fClass;
bool fAttached;
}NativeContext;
NativeContext gContext;
// Called from Java to open a native session
jint NativeOpen(JNIEnv * env , jobject obj, jint ref)
{
....
// Keep
jclass cls = (*env)->GetObjectClass(env, obj);
gContext.fClass = (*env)->NewGlobalRef(env,cls);
gContext.fObj = (*env)->NewGlobalRef(env,obj);
gContext.fMid = (*env)->GetMethodID(env, gContext.fClass,
"JavaCallBack", "()V");
gContext.fAttached = false;
...
}
// Called from Java to close a native session
jint NativeClose(JNIEnv * env , jobject obj, jint ref)
{
.....
(*gContext.fEnv)->DeleteGlobalRef(gContext.fEnv,gContext.fClass);
(*cgContext.fEnv)->DeleteGlobalRef(gContext.fEnv,gContext.fObj);
....
}
// Called from the C real-time Midi I/O callback
void NativeCallback()
{
int res;
jsize size = 0;
if (!gContext.fAttached ) { // First call, attach the IOProc
thread to the JVM
res = JNI_GetCreatedJavaVMs(&jvm, 1,&size );
if (res < 0) {
printf("Can't get Java VM\n");
}
res = (*jvm)->AttachCurrentThread(jvm, gContext.fEnv, NULL);
gContext.fAttached = true;
}
// Callback Kava code
(*gContext.fEnv)->CallVoidMethod(gContext.fEnv, gContext.fObj,
gContext.fMid);
}
Keeping the (JNIEnv *) object inside NativeOpen result in a immediate
crash, so I had to use the JNI_GetCreatedJavaVMs and AttachCurrentThread so
that to get a valid (JNIEnv *) object in order to do the CallVoidMethod
later. The code seems to work correctly but I was wondering if this method
is the correct one.
>
You could use the CAJava callbacks directly and have them do this work for
>
you - then your Java code will just run when the I/O cycle fires.
Well I don't want to use the CAJava callbacks directly but try to do what
they are doing.
Another question :
I read in some old mails that Apple do no recommend to have too much
processing be done inside the real-time IO proc :
http://lists.apple.com/archives/coreaudio-api/2001/Dec/4.html
and recommend to use another real-time, time constrained thread that will
do the real job. Both threads have to communicate using shared buffers.
But with the CoreAudio Java implementation, the Java code is directly
called inside the real-time IO proc, and examples published by Apple do all
processing inside the Java callback (like the simple AIFF player for
example).
So what are we supposed to do when developing CoreAudio Java applications
that will need lot of processing power?
Thanks
Stephane letz
Grame: Centre National de creation musicale
9, Rue du Garet
69001 Lyon
Tel: 04-72-07-37-00
Fax: 04-72-07-37-01
Web: www.grame.fr
_______________________________________________
coreaudio-api mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/coreaudio-api
Do not post admin requests to the list. They will be ignored.