[英]How to pass Void parameter with pointer from Java and how to write JNI for this?
[英]How to pass a void pointer to a struct pointer and to resolve the read memory error
目前,我正在 android 工作室制作獨立的 AEC(聲學回聲消除),並使用 Jni 在 java 和 C 之間進行鏈接。 我的演示活動 class 是
DemoActivity.java
protected void onStart() {
super.onStart();
btnStartSending.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
udp = new UDP(Integer.parseInt(etPort.getText().toString()), etIpAddress.getText().toString());
audioRecord = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, 8000,
AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, 640);
audioRecord.startRecording();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
Log.e(TAG,"the manually initialized audioData"+Arrays.toString(audioData));
audioRecord.read(audioData, 0, audioData.length);
Log.e(TAG, "SENDING DATA: " + audioData.length);
byte[] dataToSend = new byte[320];
Log.e(TAG,"RECORDED_DATA:"+Arrays.toString(audioData));
dataToSend = AECM_Processing(audioData);
Log.e(TAG,"DATA_TO_SEND: "+Arrays.toString(audioData));
}
}
}).start();
}
});
這里它調用 AECM_Processing() function,它也在 class 中定義。
public byte[] AECM_Processing(byte[] audioBytes) {
byte[] aecBuf = null;
Log.d("Android AECM Example - ", " Input Byte Data: " + Arrays.toString(audioBytes));
try {
aecm = new MobileAEC(MobileAEC.SamplingFrequency.FS_8000Hz);
aecm.setAecmMode(MobileAEC.AggressiveMode.MOST_AGGRESSIVE).prepare();
final int cacheSize = 320;
short[] aecTmpIn = new short[cacheSize / 2];
short[] aecTmpOut = new short[cacheSize / 2];
ByteBuffer.wrap(audioBytes).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(aecTmpIn);
aecm.farendBuffer(aecTmpIn, cacheSize / 2);
aecm.echoCancellation(aecTmpIn, null, aecTmpOut, (short) (cacheSize / 2), (short) 10);
// output
aecBuf = new byte[cacheSize];
ByteBuffer.wrap(aecBuf).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().put(aecTmpOut);
// aecm procession, for now the echo tail is hard-coded 10ms,
// but you
// should estimate it correctly each time you call
// echoCancellation, otherwise aecm
// cannot work.
} catch (Exception e) {
e.printStackTrace();
}
Log.d("Android AECM Example - ", " Processed Bytes: " + Arrays.toString(aecBuf));
return aecBuf;
}
我的 Jni 被定義為
JNIEXPORT jint JNICALL Java_com_example_audioProcessing_MobileAEC_nativeInitializeAecmInstance
(JNIEnv *env, jclass jclazz, jint aecmHandler, jint sampFreq)
{
//__android_log_print(ANDROID_LOG_ERROR, APPNAME, ":::AEC-Wrapper::: nativeInitializeAecmInstance Method- The value of Method: %s", "Android AEC Module");
void *aecmInst = (void *)(intptr_t) aecmHandler;
//void *aecmInst = (void *)aecmHandler;
if (aecmInst == NULL)
{
__android_log_print(ANDROID_LOG_ERROR, APPNAME, ":::AEC-Wrapper::: nativeInitializeAecmInstance Method- The value of aecmInst: %p", aecmInst);
return -1;
}
return WebRtcAecm_Init(aecmInst, sampFreq);
}
這里它調用WebRtcAecm_Init() function 定義為:
int32_t WebRtcAecm_Init(void *aecmInst, int32_t sampling_rate)
{
aecmob_t *aecm = aecmInst;
AecmConfig aecConfig;
if (aecm == NULL)
{
return -1;
}
if (sampling_rate != 8000 && sampling_rate != 16000)
{
aecm->lastError = AECM_BAD_PARAMETER_ERROR;
return -1;
}
if (sampling_rate == 8000 || sampling_rate == 16000)
{
aecm->sampFreq = sampling_rate; // code of WEBRTC
}
//Initialize AECM core
if (WebRtcAecm_InitCore(aecm->aecmCore, aecm->sampFreq) == -1)
{
aecm->lastError = AECM_UNSPECIFIED_ERROR;
return -1;
}
// Initialize farend buffer
if (WebRtc_InitBuffer(aecm->farendBuf) == -1)
{
aecm->lastError = AECM_UNSPECIFIED_ERROR;
return -1;
}
aecm->initFlag = kInitCheck; // indicates that initialization has been done
aecm->delayChange = 1;
aecm->sum = 0;
aecm->counter = 0;
aecm->checkBuffSize = 1;
aecm->firstVal = 0;
aecm->ECstartup = 1;
aecm->bufSizeStart = 0;
aecm->checkBufSizeCtr = 0;
aecm->filtDelay = 0;
aecm->timeForDelayChange = 0;
aecm->knownDelay = 0;
aecm->lastDelayDiff = 0;
memset(&aecm->farendOld[0][0], 0, 160);
// Default settings.
aecConfig.cngMode = AecmTrue;
aecConfig.echoMode = 3;
if (WebRtcAecm_set_config(aecm, aecConfig) == -1)
{
aecm->lastError = AECM_UNSPECIFIED_ERROR;
return -1;
}
return 0;
}
當我嘗試構建應用程序然后運行它時,應用程序崩潰並給出一個錯誤
致命信號 11 (SIGSEGV),代碼 1 (SEGV_MAPERR),tid 17308 (Thread-6) 中的故障地址 0x2dc52700,pid 17225 (om.example.Aecm)
有人可以幫我解決這個問題嗎?
目前,我正在 android 工作室制作獨立的 AEC(聲學回聲消除),並使用 Jni 在 java 和 C 之間進行鏈接。 我的演示活動 class 是
DemoActivity.java
protected void onStart() {
super.onStart();
btnStartSending.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
udp = new UDP(Integer.parseInt(etPort.getText().toString()), etIpAddress.getText().toString());
audioRecord = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, 8000,
AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, 640);
audioRecord.startRecording();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
Log.e(TAG,"the manually initialized audioData"+Arrays.toString(audioData));
audioRecord.read(audioData, 0, audioData.length);
Log.e(TAG, "SENDING DATA: " + audioData.length);
byte[] dataToSend = new byte[320];
Log.e(TAG,"RECORDED_DATA:"+Arrays.toString(audioData));
dataToSend = AECM_Processing(audioData);
Log.e(TAG,"DATA_TO_SEND: "+Arrays.toString(audioData));
}
}
}).start();
}
});
這里它調用 AECM_Processing() function,它也在 class 中定義。
public byte[] AECM_Processing(byte[] audioBytes) {
byte[] aecBuf = null;
Log.d("Android AECM Example - ", " Input Byte Data: " + Arrays.toString(audioBytes));
try {
aecm = new MobileAEC(MobileAEC.SamplingFrequency.FS_8000Hz);
aecm.setAecmMode(MobileAEC.AggressiveMode.MOST_AGGRESSIVE).prepare();
final int cacheSize = 320;
short[] aecTmpIn = new short[cacheSize / 2];
short[] aecTmpOut = new short[cacheSize / 2];
ByteBuffer.wrap(audioBytes).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(aecTmpIn);
aecm.farendBuffer(aecTmpIn, cacheSize / 2);
aecm.echoCancellation(aecTmpIn, null, aecTmpOut, (short) (cacheSize / 2), (short) 10);
// output
aecBuf = new byte[cacheSize];
ByteBuffer.wrap(aecBuf).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().put(aecTmpOut);
// aecm procession, for now the echo tail is hard-coded 10ms,
// but you
// should estimate it correctly each time you call
// echoCancellation, otherwise aecm
// cannot work.
} catch (Exception e) {
e.printStackTrace();
}
Log.d("Android AECM Example - ", " Processed Bytes: " + Arrays.toString(aecBuf));
return aecBuf;
}
我的 Jni 被定義為
JNIEXPORT jint JNICALL Java_com_example_audioProcessing_MobileAEC_nativeInitializeAecmInstance
(JNIEnv *env, jclass jclazz, jint aecmHandler, jint sampFreq)
{
//__android_log_print(ANDROID_LOG_ERROR, APPNAME, ":::AEC-Wrapper::: nativeInitializeAecmInstance Method- The value of Method: %s", "Android AEC Module");
void *aecmInst = (void *)(intptr_t) aecmHandler;
//void *aecmInst = (void *)aecmHandler;
if (aecmInst == NULL)
{
__android_log_print(ANDROID_LOG_ERROR, APPNAME, ":::AEC-Wrapper::: nativeInitializeAecmInstance Method- The value of aecmInst: %p", aecmInst);
return -1;
}
return WebRtcAecm_Init(aecmInst, sampFreq);
}
這里它調用WebRtcAecm_Init() function 定義為:
int32_t WebRtcAecm_Init(void *aecmInst, int32_t sampling_rate)
{
aecmob_t *aecm = aecmInst;
AecmConfig aecConfig;
if (aecm == NULL)
{
return -1;
}
if (sampling_rate != 8000 && sampling_rate != 16000)
{
aecm->lastError = AECM_BAD_PARAMETER_ERROR;
return -1;
}
if (sampling_rate == 8000 || sampling_rate == 16000)
{
aecm->sampFreq = sampling_rate; // code of WEBRTC
}
//Initialize AECM core
if (WebRtcAecm_InitCore(aecm->aecmCore, aecm->sampFreq) == -1)
{
aecm->lastError = AECM_UNSPECIFIED_ERROR;
return -1;
}
// Initialize farend buffer
if (WebRtc_InitBuffer(aecm->farendBuf) == -1)
{
aecm->lastError = AECM_UNSPECIFIED_ERROR;
return -1;
}
aecm->initFlag = kInitCheck; // indicates that initialization has been done
aecm->delayChange = 1;
aecm->sum = 0;
aecm->counter = 0;
aecm->checkBuffSize = 1;
aecm->firstVal = 0;
aecm->ECstartup = 1;
aecm->bufSizeStart = 0;
aecm->checkBufSizeCtr = 0;
aecm->filtDelay = 0;
aecm->timeForDelayChange = 0;
aecm->knownDelay = 0;
aecm->lastDelayDiff = 0;
memset(&aecm->farendOld[0][0], 0, 160);
// Default settings.
aecConfig.cngMode = AecmTrue;
aecConfig.echoMode = 3;
if (WebRtcAecm_set_config(aecm, aecConfig) == -1)
{
aecm->lastError = AECM_UNSPECIFIED_ERROR;
return -1;
}
return 0;
}
當我嘗試構建應用程序然后運行它時,應用程序崩潰並給出一個錯誤
致命信號 11 (SIGSEGV),代碼 1 (SEGV_MAPERR),tid 17308 (Thread-6) 中的故障地址 0x2dc52700,pid 17225 (om.example.Aecm)
有人可以幫我解決這個問題嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.