1

I implemented the audio playback successfully but a frequent problem comes up where a sharp auditory glitch occurs when "next song" is clicked from JAVA. This sound glitch elapses approx. around 100ms. And occurs more frequently before the next song starts playing.

Please importantly note this: I call "delete" on every variable class and "free" stereobuffers (setdestroyallthreads) at the end of every playback, then "process"(process) method before every playback starts.

From Java, the transition sequence looks like this;

PlayerClass.setDestroyAllThreads( );
PlayerClass.open("new_path", sampleRate, bufferSize );
PlayerClass.play( );

Here is my snippet;

    static void playerEventCallbackA(void *clientData, SuperpoweredAdvancedAudioPlayerEvent event, void * __unused value) {
    if (event == SuperpoweredAdvancedAudioPlayerEvent_LoadSuccess) {
        SuperpoweredAdvancedAudioPlayer *player = *((SuperpoweredAdvancedAudioPlayer **)clientData);

    }else if (event == SuperpoweredAdvancedAudioPlayerEvent_EOF) {

        playerBass->pause();
        playerB->pause();

        finishedPlaying = true;

    }else if (event == SuperpoweredAdvancedAudioPlayerEvent_LoadError) {

    };
}


static bool audioProcessing(void *clientdata, short int *audioIO, int numberOfSamples, int __unused samplerate) {
    return ((Eve *)clientdata)->process(audioIO, (unsigned int)numberOfSamples);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
Eve::Eve(const char *path,unsigned int samplerate,unsigned int buffersize) : activeFx(0), crossValue(0.0f), volBass(1.0f * headroom), volB(1.0f * headroom) {
    stereoBuffer = (float *)memalign(16,(buffersize + 16) * sizeof(float) * 2);

    playerBass = new SuperpoweredAdvancedAudioPlayer(&playerBass , playerEventCallbackA, samplerate, 0);
    playerB = new SuperpoweredAdvancedAudioPlayer(&playerB, playerEventCallbackB, samplerate, 0);
    filterb = new SuperpoweredFilter(SuperpoweredFilter_Resonant_Lowpass, samplerate*0.98);
    spatializer = new SuperpoweredSpatializer(samplerate);

    playerBass->open(path);
    playerB->open(path);

    finishedPlaying = false;

    playerBass->syncMode = playerB->syncMode = SuperpoweredAdvancedAudioPlayerSyncMode_TempoAndBeat;
    audioSystem = new SuperpoweredAndroidAudioIO(samplerate, buffersize, false, true, audioProcessing, this, -1, SL_ANDROID_STREAM_MEDIA, buffersize * 2);
}


Eve::~Eve() {
    delete playerBass;
    delete playerB;
    delete spatializer;
    delete filterb;
    delete audioSystem;

    finishedPlaying = false, playingNow = false, pausedNow = false, processed = false, hd = false;
}

void Eve::onPlay() {

    playerBass->play(false);
    playerB->play(false);
    playingNow = true;

}

void Eve::setBassValue(int bass) {


    filterb->setResonantParameters(floatToFrequency(0.2f),ebass);
    filterb->enable(true);

}

void Eve::setDestroyAllThreads(){

    delete playerBass;
    delete playerB;
    delete spatializer;
    delete filterb;
    delete audioSystem;

    finishedPlaying = false, playingNow = false, pausedNow = false, processed = false, hd = false;
}




bool Eve::process(short int *output, unsigned int numberOfSamples) {

    bool masterIsA = (crossValue <= 0.5f);
    double masterBpm = masterIsA ? playerBass->currentBpm : playerB->currentBpm;
    double msElapsedSinceLastBeatA = playerBass->msElapsedSinceLastBeat;

    bool silence = !playerBass->process(stereoBuffer, false, numberOfSamples*1, volBass, masterBpm, playerB->msElapsedSinceLastBeat);
    processed = true;

    filterb->process(stereoBuffer, stereoBuffer, numberOfSamples);
    if (playerB->process(stereoBuffer, !silence, numberOfSamples, volB, masterBpm, msElapsedSinceLastBeatA)) silence = false;

    spatializer->process(stereoBuffer, stereoBuffer, (float*)output, (float*)output, numberOfSamples, true);
    SuperpoweredFloatToShortInt(stereoBuffer, output, numberOfSamples);
    return !silence;
}


static Eve *eve = NULL;

extern "C" JNIEXPORT void Java_com_EvePlayer_Eve(JNIEnv *javaEnvironment, jobject self, jstring songPath, jint samplerate, jint buffersize) {

    const char *path = javaEnvironment->GetStringUTFChars(songPath, JNI_FALSE);
    eve = new Eve(path,(unsigned int)samplerate,(unsigned int)buffersize);
    javaEnvironment->ReleaseStringUTFChars(songPath, path);

}

extern "C" JNIEXPORT void Java_com_EvePlayer_SetTempFolder(JNIEnv *javaEnvironment, jobject __unused obj, jstring path) {
    const char *str = javaEnvironment->GetStringUTFChars(path, 0);
    SuperpoweredAdvancedAudioPlayer::setTempFolder(str);
    javaEnvironment->ReleaseStringUTFChars(path, str);
}

extern "C" JNIEXPORT void Java_com_EvePlayer_evePlay(JNIEnv *javaEnvironment, jobject self){
    eve->onPlay();
}

extern "C" JNIEXPORT void Java_com_EvePlayer_setDestroyAllThreads(JNIEnv *javaEnvironment, jobject self) {
    eve->setDestroyAllThreads();
}

1 Answers1

0

Destroy the audio I/O ("audioSystem" in your code) first. The audio I/O invokes your audio processing callback periodically, so it needs to be destroyed first, it will use deleted objects otherwise.

Gabor Szanto
  • 1,329
  • 8
  • 12