0

我对 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

我想不断更新从这个while循环内部接收到的最大频率的TextView:

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 和 jobject,但我还没有成功。我看到它们在这里没有使用:

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

从音频处理内部?非常感谢!

4

1 回答 1

1

不建议从音频处理线程调用 Java,因为它涉及多个阻塞调用。

Env 和 thiz 是特定于线程的,因线程而异。让它们用于音频处理线程是一个很大的禁忌。

最好反过来想:

  • 使用您要显示的结果更新音频处理回调中的数组。
  • 创建一个 JNI 函数以将数组的值返回给 Java。
  • 定期从 Runnable(在 Java 中)调用该 JNI 函数。
于 2017-03-31T13:34:12.327 回答