简体   繁体   中英

Android NDK - referencing JNIEnv to call Java from C++

I'm very new to C++ and I'm working with the Superpowered FrequencyDomain example here: https://github.com/superpoweredSDK/Low-Latency-Android-Audio-iOS-Audio-Engine/blob/master/Examples_Android/FrequencyDomain/app/src/main/jni/FrequencyDomain.cpp

I want to continuously update a TextView with the loudest frequency being received from inside this while loop:

static bool audioProcessing(void * __unused clientdata, short int *audioInputOutput, int numberOfSamples, int __unused samplerate) {
SuperpoweredShortIntToFloat(audioInputOutput, inputBufferFloat, (unsigned int)numberOfSamples); // Converting the 16-bit integer samples to 32-bit floating point.
frequencyDomain->addInput(inputBufferFloat, numberOfSamples); // Input goes to the frequency domain.

// In the frequency domain we are working with 1024 magnitudes and phases for every channel (left, right), if the fft size is 2048.
while (frequencyDomain->timeDomainToFrequencyDomain(magnitudeLeft, magnitudeRight, phaseLeft, phaseRight)) {

I think I need to do something like this:

jclass classs = env->FindClass("com/superpowered/frequencydomain/MainActivity");
jmethodID method = env->GetMethodID(classs, "updateTextViewFromJNI","(I)V");
env->CallVoidMethod(thiz, method, myJavaInt);

but those are the only lines in a example C++ function which already has access to env and thiz:

void callJavaMethod(JNIEnv* env,jobject thiz) {...previous 3 lines...}

Calling a Java function like this:

public void updateTextViewFromJNI(int i) {
    txtLoudestFreq.setText(Integer.toString(i));
}

I've been trying different ways to getting to JNIEnv and jobject, but I haven't succeeded yet. I see they're unused here:

extern "C" JNIEXPORT void Java_com_superpowered_frequencydomain_MainActivity_FrequencyDomain(JNIEnv * __unused javaEnvironment, jobject __unused obj, jint samplerate, jint buffersize)

but I'm not sure how to get access to them in:

audioProcessing

I've tried making them global. From what I've read, I'm trying to get a reference to them, but missing how to do it. What steps do I need to do in order to be able to call something like this:

env->CallVoidMethod(thiz, method, myJavaInt);

from inside audioProcessing? Thank you very much!

Calling Java is not recommended from an audio processing thread, as it involves multiple blocking calls.

Env and thiz are thread specific, different from thread to thread. Getting them for the audio processing thread is a big no-no.

It's better to think the other way around:

  • Update an array in the audio processing callback with the results you'd like to display.
  • Create a JNI function to return with the values of the array to Java.
  • Periodically call that JNI function from a Runnable (in Java).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM