Game Development Reference
In-Depth Information
/****************************************************************
* C - CALLBACKS - Entry points
*****************************************************************/
private static void OnInitAudio(int freq, int channels, int bits) {
Log.d(TAG, "NATIVE THREAD::OnInitAudio Au Start -> freq:" + freq
+ " channels:" + channels + " bits:" + bits);
// start audio
start(freq, channels, bits);
}
private static void OnLockAudio() {
mAudioLocked = true;
}
private static void OnUnLockAudio(){
mAudioLocked = false;
}
private static void OnCloseAudio(){
stop();
}
}
Now you need a C implementation of PaintAudio (see Listing 2-5). Notice the third argument:
jobject buf
, which encapsulates a reference to the
ByteBuffer
used to store the audio data.
You can access a Java
ByteBuffer
memory address and capacity directly from C by calling
the JNI functions:
GetDirectBufferAddress
and
GetDirectBufferCapacity
, respectively. The
prototype
paint_audio
defines the C function that writes the audio data into the game audio
buffer. PaintAudio calls this subroutine to fill the Java
ByteBuffer
with data from the native
audio buffer. The final result is a Java thread that receives a sequence of audio bytes, which
in turn are sent to the Android AudioTrack for playback.
Listing 2-5. C Companion for NativeAudio.java
// engine audio renderer
extern int paint_audio (void *unused, void * stream, int len);
JNIEXPORT jint JNICALL Java_ NativeAudio_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 );
}