Android NDK — ссылка на JNIEnv для вызова Java из переполнения стека

Я очень плохо знаком с C ++ и работаю с примером Superpowered FrequencyDomain здесь:
https://github.com/superpoweredSDK/Low-Latency-Android-Audio-iOS-Audio-Engine/blob/master/Examples_Android/FrequencyDomain/app/src/main/jni/FrequencyDomain.cpp

Я хочу постоянно обновлять TextView с самой громкой частотой, получаемой из этого цикла while:

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)) {

Я думаю, что мне нужно сделать что-то вроде этого:

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

но это единственные строки в примере функции C ++, которая уже имеет доступ к env и thiz:

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

Вызов функции Java следующим образом:

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

Я пробовал разные способы добраться до JNIEnv и задания, но пока не удалось. Я вижу, что они здесь не используются:

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

но я не уверен, как получить к ним доступ в:

audioProcessing

Я пытался сделать их глобальными. Из того, что я прочитал, я пытаюсь получить ссылку на них, но не знаю, как это сделать. Какие шаги мне нужно сделать, чтобы иметь возможность вызывать что-то вроде этого:

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

изнутри аудиообработка? Большое спасибо!

0

Решение

Вызов Java не рекомендуется из потока обработки звука, поскольку он включает в себя несколько блокирующих вызовов.

Env и thiz зависят от потока, отличаются от потока к потоку. Получение их для потока обработки аудио — это большое нет-нет.

Лучше подумать наоборот:

  • Обновите массив в обратном вызове обработки аудио с результатами, которые вы хотели бы
    для отображения.
  • Создайте функцию JNI для возврата со значениями массива в Java.
  • Периодически вызывайте эту функцию JNI из Runnable (в Java).
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]