我成功实现了音频播放,但经常出现一个问题,即从 JAVA 单击“下一首歌曲”时会出现明显的听觉故障。这个声音故障大约会过去。大约 100 毫秒。并且在下一首歌曲开始播放之前更频繁地发生。
请重要地注意这一点:我在每个变量类上调用“delete”,在每次播放结束时调用“free”立体声缓冲区(setdestroyallthreads),然后在每次播放开始前调用“process”(process)方法。
从 Java 来看,转换序列是这样的;
PlayerClass.setDestroyAllThreads( );
PlayerClass.open("new_path", sampleRate, bufferSize );
PlayerClass.play( );
这是我的片段;
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();
}