簡體   English   中英

如何將 void 指針傳遞給結構指針並解決讀取 memory 錯誤

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM