0

我有一个程序可以制作频率样本并在一个短数组中返回一个样本缓冲区,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++ 中操作短数组时,我一直在寻找,但找不到如何正确操作它。有人能告诉我我该怎么做吗?

4

1 回答 1

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

应用程序.mk

APP_ABI := all
于 2013-10-04T14:41:57.173 回答