Java 短数组的JNI包装器定义
我有一个程序,它生成一个频率的样本,并在一个短数组中返回一个样本缓冲区,java代码如下:Java 短数组的JNI包装器定义,java,c++,android-ndk,java-native-interface,short,Java,C++,Android Ndk,Java Native Interface,Short,我有一个程序,它生成一个频率的样本,并在一个短数组中返回一个样本缓冲区,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 sa
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;
}
private static int=10000;
专用静态双精度_TWO_PY=8。*阿坦数学(1);
专用静态双相=0.0;
私有静态短[]采样缓冲区;
公共静态短[]buildJ(int-freq,int-sampleRate,int-bufferSize){
sampleBuffer=新的短[bufferSize];
for(int i=0;i
现在,我一直在尝试使用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;
}
}
#包括
#包括
名称空间com\u mytest\u ndktest{
静态整数AMP=10000;
静态双精度_TWO _PY=8.*atan(1.0);
静态双相=0.0;
静态jshortaray构建(JNIEnv*env、int-freq、int-sampleRate、int-bufferSize){
短采样缓冲区[bufferSize];
for(int i=0;inewshortaray(bufferSize);
env->SetShortarray区域(retval,0,bufferSize,sampleBuffer);
返回返回;
}
//JNI包装器
静态JShortaray构建(JNINEV*env、jclass clazz、jint freq、jint采样器、jint bufferSize){
返回构建(环境、频率、采样器、缓冲区大小、音频强度);
}
静态JniationMethod_表[]={
{“buildN”,“(III)[S”,(void*)buildN}
};
使用名称空间com_mytest_ndktest;
外部“C”jint JNI_OnLoad(JavaVM*vm,void*reserved){
JNIEnv*env;
if(vm->GetEnv(重新解释cast(&env),JNI\u版本1\u 6)!=JNI\u OK){
返回-1;
}否则{
jclass clazz=env->FindClass(“com/mytest/ndktest/frequencycsample”);
if(clazz){
环境->登记(分类、方法表、规模(方法表)/规模(方法表[0]);
env->DeleteLocalRef(clazz);
返回JNI_版本_1_6;
}否则{
返回-1;
}
}
}
<> p>应用程序在加载C++库时崩溃,我认为错误是在C++中操作短数组时,我一直在寻找,但是找不到如何正确地处理它。有人告诉我该怎么做吗?< /p> 我终于能够使它正常工作,看起来问题是因为没有使用的代码,这里的任何方法都是T。他完成了我在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");
}
}
将“(I;I;I)[S”更改为“(iii)[S”(去掉分号,构建n有四个int参数)。谢谢你,法登,我纠正了这些错误,但在加载时应用程序仍然崩溃。你在logcat中看到了什么?你在调用build()有四个参数,但只需要三个参数。这段代码不应该编译。因此它是真正的代码吗?@fadden我能够找到错误,我试图注册来自marakana的原始示例的另一个函数,但没有完全擦除。
#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;
}
}
}
APP_ABI := all