我有一个程序可以生成一个频率样本,并在一个短数组中返回一个样本缓冲区,java代码如下:
private static int _AMP = 10000;
private static double _TWO_PY = 8. * Math.atan(1.);
private static double _PHASE = 0.0;
private static short[] sampleBuffer;
public static short[] buildJ(int freq, int sampleRate, int bufferSize) {
sampleBuffer = new short[bufferSize];
for(int i = 0; i < bufferSize; i++){
sampleBuffer[i] = (short) (_AMP * Math.sin(_PHASE));
_PHASE += _TWO_PY * freq / sampleRate;
}
return sampleBuffer;
}
现在我一直在尝试使用ndk做同样的程序,到目前为止我做的是:
#include <jni.h>
#include <math.h>
namespace com_mytest_ndktest {
static int _AMP = 10000;
static double _TWO_PY = 8. * atan(1.0);
static double _PHASE = 0.0;
static jshortArray build(JNIEnv *env,int freq, int sampleRate, int bufferSize) {
short sampleBuffer[bufferSize];
for(int i = 0; i < bufferSize; i++){
sampleBuffer[i] = (_AMP * sin(_PHASE));
_PHASE += _TWO_PY * freq / sampleRate;
}
jshortArray retval = env->NewShortArray(bufferSize);
env->SetShortArrayRegion(retval,0,bufferSize,sampleBuffer);
return retval;
}
//JNI Wrapper
static jshortArray buildN(JNIEnv *env, jclass clazz, jint freq, jint sampleRate, jint bufferSize) {
return build(env, freq, sampleRate, bufferSize, audioIntensity);
}
static JNINativeMethod method_table[] = {
{ "buildN", "(III)[S", (void *) buildN }
};
using namespace com_mytest_ndktest;
extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return -1;
} else {
jclass clazz = env->FindClass("com/mytest/ndktest/FrequencySample");
if (clazz) {
env->RegisterNatives(clazz, method_table, sizeof(method_table) / sizeof(method_table[0]));
env->DeleteLocalRef(clazz);
return JNI_VERSION_1_6;
} else {
return -1;
}
}
}
应用程序在加载c ++库时崩溃,我相信错误是在c ++中操作短数组时我一直在寻找arround但是无法找到如何正确操作它。有人会告诉我该怎么办?
答案 0 :(得分:0)
最后我能够使它工作,看起来问题是因为未使用的代码,这里的任何方法都是完整的非自动生成的代码,我用于检查java中的处理时间和c ++有效。
在src目录中: MainActivity.java
package com.mytest.ndktest;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends Activity {
TextView _tvResult;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
_tvResult = (TextView)findViewById(R.id.tvResult);
}
public void bGo_Click(View view) {
long time = System.currentTimeMillis();
FrequencySample.buildJ(1000, 22050, 8192);
time = System.currentTimeMillis() - time;
_tvResult.append( String.format("\n(%dms)",time));
time = System.currentTimeMillis();
FrequencySample.buildN(1000, 22050, 8192);
time = System.currentTimeMillis() - time;
_tvResult.append(String.format("\n(%dms)", time));
}
}
FrequencySample.java
package com.mytest.ndktest;
public class FrequencySample {
private static int _AMP = 10000;
private static double _TWO_PY = 8. * Math.atan(1.);
private static double _PHASE = 0.0;
private static short[] _SAMPLE_BUFFER;
/* Creates a frequency sample
* Stores frequency samples in a sample buffer
*/
public static short[] buildJ(int freq, int sampleRate, int bufferSize) {
_SAMPLE_BUFFER = new short[bufferSize];
for(int i = 0; i < bufferSize; i++){
_SAMPLE_BUFFER[i] = (short) (_AMP * Math.sin(_PHASE));
_PHASE += _TWO_PY * freq / sampleRate;
}
return _SAMPLE_BUFFER;
}
public static native short[] buildN(int freq, int sampleRate, int bufferSize);
static {
System.loadLibrary("ndktest");
}
}
在jni目录中: ndktest.cpp
#include <jni.h>
#include <math.h>
namespace com_mytest_ndktest {
static int _AMP = 10000;
static double _TWO_PY = 8. * atan(1.0);
static double _PHASE = 0.0;
static jshortArray build(JNIEnv *env,int freq, int sampleRate, int bufferSize) {
short sampleBuffer[bufferSize];
for(int i = 0; i < bufferSize; i++){
sampleBuffer[i] = (_AMP * sin(_PHASE));
_PHASE += _TWO_PY * freq / sampleRate;
}
jshortArray retval = env->NewShortArray(bufferSize);
env->SetShortArrayRegion(retval,0,bufferSize,sampleBuffer);
return retval;
}
//JNI Wrapper
static jshortArray buildN(JNIEnv *env, jclass clazz, jint freq, jint sampleRate, jint bufferSize) {
return build(env, freq, sampleRate, bufferSize);
}
static JNINativeMethod method_table[] = {
{ "buildN", "(III)[S", (void *) buildN }
};
}
using namespace com_mytest_ndktest;
extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return -1;
} else {
jclass clazz = env->FindClass("com/mytest/ndktest/FrequencySample");
if (clazz) {
env->RegisterNatives(clazz, method_table, sizeof(method_table) / sizeof(method_table[0]));
env->DeleteLocalRef(clazz);
return JNI_VERSION_1_6;
} else {
return -1;
}
}
}
Application.mk
APP_ABI := all