0

I am using fmod library in my Android app to filter sound. There is a crash in GP console and I can't reproduce it on my device. Here is the backtrace:

JNI DETECTED ERROR IN APPLICATION: java_object == null
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

backtrace:
  #00  pc 0x000000000005c444  /apex/com.android.runtime/lib64/bionic/libc.so (abort+180)
  #01  pc 0x000000000093091c  /apex/com.android.art/lib64/libart.so (art::Runtime::Abort(char const*)+344)
  #02  pc 0x00000000000160fc  /apex/com.android.art/lib64/libbase.so (android::base::SetAborter(std::__1::function<void (char const*)>&&)::$_0::__invoke(char const*)+80)
  #03  pc 0x00000000000156d0  /apex/com.android.art/lib64/libbase.so (android::base::LogMessage::~LogMessage()+516)
  #04  pc 0x0000000000442390  /apex/com.android.art/lib64/libart.so (art::JavaVMExt::JniAbort(char const*, char const*)+1696)
  #05  pc 0x0000000000525278  /apex/com.android.art/lib64/libart.so (art::JNI<false>::GetObjectClass(_JNIEnv*, _jobject*)+468)
  #06  pc 0x0000000000005188  /data/app/~~Z_IFePTytjAkWkrXxToe1w==/com.my.app.package-y8HMT5XoWD5wlTXbflg7-A==/split_config.arm64_v8a.apk!libexample.so (Common_GetPropertyValue(int)+136) (BuildId: 7264cb4aa1e9a168b62455f5db85b4cf6e74945c)
  #07  pc 0x000000000000623c  /data/app/~~Z_IFePTytjAkWkrXxToe1w==/com.my.app.package-y8HMT5XoWD5wlTXbflg7-A==/split_config.arm64_v8a.apk!libexample.so (FMOD_LivePreview(char const*, float)+728) (BuildId: 7264cb4aa1e9a168b62455f5db85b4cf6e74945c)
  #08  pc 0x0000000000005470  /data/app/~~Z_IFePTytjAkWkrXxToe1w==/com.my.app.package-y8HMT5XoWD5wlTXbflg7-A==/split_config.arm64_v8a.apk!libexample.so (Java_com_my_package_activitySound_SoundJavaActivity_fmodStartPlay+164) (BuildId: 7264cb4aa1e9a168b62455f5db85b4cf6e74945c)
  #09  pc 0x000000000037412c  /data/misc/apexdata/com.android.art/dalvik-cache/arm64/boot.oat (art_jni_trampoline+124)
  #10  pc 0x0000000000780780  /apex/com.android.art/lib64/libart.so (nterp_helper+5648)
  #11  pc 0x00000000003e3282  /data/app/~~Z_IFePTytjAkWkrXxToe1w==/com.my.app.package-y8HMT5XoWD5wlTXbflg7-A==/base.apk (com.my.package.activitySound.SoundJavaActivity.lambda$playSound$7+18)
  #12  pc 0x00000000007800c4  /apex/com.android.art/lib64/libart.so (nterp_helper+3924)
  #13  pc 0x00000000003e2ef0  /data/app/~~Z_IFePTytjAkWkrXxToe1w==/com.my.app.package-y8HMT5XoWD5wlTXbflg7-A==/base.apk (com.my.package.activitySound.SoundJavaActivity.$r8$lambda$AaHEezBg_mfaszt4Iimkszl0fc4)
  #14  pc 0x000000000077f1a4  /apex/com.android.art/lib64/libart.so (nterp_helper+52)
  #15  pc 0x00000000003e28c8  /data/app/~~Z_IFePTytjAkWkrXxToe1w==/com.my.app.package-y8HMT5XoWD5wlTXbflg7-A==/base.apk (com.my.package.activitySound.SoundJavaActivity$$ExternalSyntheticLambda2.run+4)
  #16  pc 0x00000000005f49a4  /data/misc/apexdata/com.android.art/dalvik-cache/arm64/boot.oat (java.util.concurrent.ThreadPoolExecutor.runWorker+724)
  #17  pc 0x00000000005f22d8  /data/misc/apexdata/com.android.art/dalvik-cache/arm64/boot.oat (java.util.concurrent.ThreadPoolExecutor$Worker.run+56)
  #18  pc 0x00000000004ccc50  /data/misc/apexdata/com.android.art/dalvik-cache/arm64/boot.oat (java.lang.Thread.run+64)
  #19  pc 0x000000000036d574  /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612)
  #20  pc 0x0000000000358bc0  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+132)
  #21  pc 0x0000000000944608  /apex/com.android.art/lib64/libart.so (art::detail::ShortyTraits<(char)86>::Type art::ArtMethod::InvokeInstance<(char)86>(art::Thread*, art::ObjPtr<art::mirror::Object>, art::detail::ShortyTraits<>::Type...)+60)
  #22  pc 0x0000000000625d24  /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback(void*)+1344)
  #23  pc 0x00000000006257d4  /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallbackWithUffdGc(void*)+8)
  #24  pc 0x00000000000c9fb0  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208)
  #25  pc 0x000000000005dd90  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64)

And here are the methods:

// Global JavaVM pointer
JavaVM *gJvm = nullptr;

jobject gMainActivityObject = nullptr;
    void
    Java_com_baby_hearth_monitor_activityEdit_EditJavaActivity_fmodStartPlay(JNIEnv *env, jobject thiz,
                                                                             jstring index, jfloat f) {
    //    Log
    
        soundShouldStop = false;
        if (gMainActivityObject) {
            printf("Deleting old global reference for gMainActivityObject\n");
            env->DeleteGlobalRef(gMainActivityObject);
        }
        gMainActivityObject = env->NewGlobalRef(thiz);
        printf("gMainActivityObject set with a new global reference\n");
    
        const char *nativeString = env->GetStringUTFChars(index, nullptr);
        FMOD_LivePreview(nativeString, f);
        env->ReleaseStringUTFChars(index, nativeString);
    }

    int FMOD_LivePreview(const char *fileName, float f) {
        FMOD::System *system = 0;
        FMOD::Sound *sound = 0;
        FMOD::Channel *channel = 0;
        FMOD::ChannelGroup *mastergroup = 0;
        FMOD::DSP *dsplowpass = 0;
        FMOD::DSP *dsppitch = 0;
        FMOD::DSP *dspnormalize = 0;
    
        unsigned int version;
        void *extradriverdata = 0;
    
        unsigned int currentPosition = 0;
        unsigned int startFrom = 0;
        unsigned int endsTo = 0;
        unsigned int lenms = 0;
    
    
        Common_Init(&extradriverdata);
    
        /*
         Create a System object and initialize
         */
        result = FMOD::System_Create(&system);
        ERRCHECK(result);
    
        result = system->getVersion(&version);
        ERRCHECK(result);
    
        if (version < FMOD_VERSION) {
            Common_Fatal("FMOD lib version %08x doesn't match header version %08x", version,
                         FMOD_VERSION);
        }
    
        result = system->init(32, FMOD_INIT_NORMAL, extradriverdata);
        ERRCHECK(result);
    
        result = system->getMasterChannelGroup(&mastergroup);
        ERRCHECK(result);
    
    
        result = system->createSound(Common_MediaPath(fileName), FMOD_DEFAULT, 0, &sound);
        ERRCHECK(result);
    
        /*
         Create some effects to play with
         */
        result = system->createDSPByType(FMOD_DSP_TYPE_LOWPASS, &dsplowpass);
        ERRCHECK(result);
    
        result = system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &dsppitch);
        ERRCHECK(result);
        result = system->createDSPByType(FMOD_DSP_TYPE_NORMALIZE, &dspnormalize);
        ERRCHECK(result);
    
        /*
         Add them to the master channel group.  Each time an effect is added (to position 0) it pushes the others down the list.
         */
        result = mastergroup->addDSP(0, dsplowpass);
        ERRCHECK(result);
    
        result = mastergroup->addDSP(0, dsppitch);
        ERRCHECK(result);
        result = mastergroup->addDSP(0, dspnormalize);
        ERRCHECK(result);
    
        /*
         By default, bypass all effects.  This means let the original signal go through without processing.
         It will sound 'dry' until effects are enabled by the user.
         */
        result = dsplowpass->setBypass(true);
        ERRCHECK(result);
    
        result = dsppitch->setBypass(true);
        ERRCHECK(result);
        result = dspnormalize->setBypass(true);
        ERRCHECK(result);
    
        /*
         Main loop
         */
        bool soundStarted = false;
        Common_ShouldPlay();
        do {
            if (!soundStarted) {
                channel->stop();
                sound->setDefaults(f, 0);
            }
    
            channel->setLoopCount(10000);
    
    
            channel->setMode(FMOD_LOOP_NORMAL);
    
    
            channel->setFrequency(f);
    
            float pitch = Common_GetPropertyValue(0);
            float cutoff = Common_GetPropertyValue(1);
            float maxAmp = Common_GetPropertyValue(2);
            float threshold = Common_GetPropertyValue(3);
    
            dsppitch->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH, pitch);
            dsppitch->setBypass(false);
            dsplowpass->setParameterFloat(FMOD_DSP_LOWPASS_CUTOFF, cutoff);
            dsplowpass->setBypass(false);
            dspnormalize->setParameterFloat(FMOD_DSP_NORMALIZE_MAXAMP, maxAmp);
            dspnormalize->setBypass(false);
            dspnormalize->setParameterFloat(FMOD_DSP_NORMALIZE_THRESHOLD, threshold);
            dspnormalize->setBypass(false);
    
            if (!soundStarted) {
                soundStarted = true;
                system->playSound(sound, 0, false, &channel);
                sound->getLength(&lenms, FMOD_TIMEUNIT_MS);
                Common_SoundStarted(lenms);
            }
    
            result = system->update();
    
            sound->getLength(&lenms, FMOD_TIMEUNIT_MS);
            startFrom = 0.0; // lenms * Common_GetStartPosition();
            endsTo = lenms; // * Common_GetEndPosition();
    
            channel->getPosition(&currentPosition, FMOD_TIMEUNIT_MS);
    
            if (currentPosition > 0) {
                if (currentPosition <= startFrom) {
                    currentPosition = startFrom;
                    result = channel->setPosition(currentPosition, FMOD_TIMEUNIT_MS);
                    ERRCHECK(result);
                }
    
                if (currentPosition >= endsTo) {
                    channel->setPosition(startFrom, FMOD_TIMEUNIT_MS);
                    currentPosition = startFrom;
    
                    if (!Common_SoundLoopActive()) {
                        Common_Stop();
                    }
                }
            }
            bool isPlaying;
            channel->isPlaying(&isPlaying);
    
            if (!isPlaying) {
                Common_Stop();
            }
    
            Common_UpdateCurrentTime(float(currentPosition) / float(lenms));
            Common_Sleep(1);
        } while (!Common_SoundShouldStop());
    
        /*
         Shut down
         */
    
        Common_SoundStoped();
    
        result = mastergroup->removeDSP(dsplowpass);
        ERRCHECK(result);
    
        result = mastergroup->removeDSP(dsppitch);
        ERRCHECK(result);
        result = mastergroup->removeDSP(dspnormalize);
        ERRCHECK(result);
    
        result = dsplowpass->release();
        ERRCHECK(result);
    
        result = dsppitch->release();
        ERRCHECK(result);
        result = dspnormalize->release();
        ERRCHECK(result);
    
        result = sound->release();
        ERRCHECK(result);
        result = system->close();
        ERRCHECK(result);
        result = system->release();
        ERRCHECK(result);
    
        Common_Close();
    
        return 0;
    }

    float Common_GetPropertyValue(int propertyIndex) {
    
        JNIEnv *gJNIEnv = getJNIEnv();
        jclass mainActivityClass = gJNIEnv->GetObjectClass(gMainActivityObject);
    
        gJNIEnv = getJNIEnv(); // Ensure valid JNIEnv
    
        float defaultValue = 1.0f;
        if (!gJNIEnv || !gMainActivityObject) {
            printf("JNI ERROR: Invalid JNIEnv or gMainActivityObject\n");
            return defaultValue; // Default value if invalid
        }
    
        if (!mainActivityClass) {
            printf("JNI ERROR: Failed to get class from gMainActivityObject\n");
            if (gJNIEnv->ExceptionCheck()) {
                gJNIEnv->ExceptionDescribe();
                gJNIEnv->ExceptionClear();
            }
            return defaultValue; // Default value if invalid
        }
    
        jmethodID methodID = gJNIEnv->GetMethodID(mainActivityClass, "fmodGetPropertyValue", "(I)F");
        if (!methodID) {
            printf("JNI ERROR: Failed to get method ID for fmodGetPropertyValue\n");
            gJNIEnv->DeleteLocalRef(mainActivityClass);
            return defaultValue; // Default value if method not found
        }
    
        float result = gJNIEnv->CallFloatMethod(gMainActivityObject, methodID, propertyIndex);
        if (gJNIEnv->ExceptionCheck()) {
            gJNIEnv->ExceptionDescribe();
            gJNIEnv->ExceptionClear();
            result = defaultValue; // Default value if exception occurs
        }
    
        gJNIEnv->DeleteLocalRef(mainActivityClass);
        return result;
    }

1 Answer 1

0

The stack trace could not be clearer: gMainActivityObject is null but you are calling GetObjectClass on it anyway. Move that call under the if (!gMainActivityObject) check instead.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.