Java 短数组的JNI包装器定义

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

我有一个程序,它生成一个频率的样本,并在一个短数组中返回一个样本缓冲区,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;
}
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