Game Development Reference
In-Depth Information
Finally, whenever you want to start the audio playback, you can simply call Nativeaudio.
start() . At that point, the Java thread fires and begins reading audio bytes from the C
library. This is not an optimal solution (the most efficient one would be to write the audio
directly from the native engine), but it works very well with no lag in sound whatsoever.
The following are some things to carefully consider:
ByteBuffer . This is critical, as the
code cannot use short or integer buffers. A direct ByteBuffer is required
because the Java virtual machine makes a best effort to perform native
I/O operations directly upon it. On the other hand, non-direct byte buffers
copy the content to (or from) an intermediate buffer before (or after)
each invocation of one of the underlying operating system's native I/O
operations.
The Java audio buffer must be a direct
The native engine should use a byte array of audio encoded in the same
format (in this case 16-bit stereo at 22 kHz), which is copied into the
Java byte buffer and then played by the audio track.
NativeAudio class requires the companion JNI C function
PaintAudio to copy the native ByteBuffer into the Java byte buffer,
as shown in Listing 6-6.
The
Listing 6-6. Companion PaintAudio JNI Function for NativeAudio
// copy len bytes of native audio into stream
extern int paint_audio (void *unused, void * stream, int len);
JNIEXPORT jint JNICALL Java_quake_jni_Natives_PaintAudio
( JNIEnv* env, jobject thiz, jobject buf )
{
void *stream;
int len;
stream = (*env)->GetDirectBufferAddress(env, buf);
len = (*env)->GetDirectBufferCapacity (env, buf);
return paint_audio ( NULL, stream, len );
}
As you can see from Listing 6-6, PaintAudio must be declared as native in the Java class
quake.jni.Natives.java . Note the calls to GetDirectBufferAddress , which fetch and return
the starting address of the memory region referenced by the given direct java.nio.Buffer .
Also note GetDirectBufferCapacity , which returns the capacity in bytes of the memory
region referenced by the given direct buffer.
Now that you have a reference to the Java byte buffer and its size, you can call the native
audio painter to fill it up.
 
Search WWH ::




Custom Search