Merge pull request #12333 from hrydgard/android-opensl-init-fix

Android OpenSL initial queue fix
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2019-09-18 00:55:16 +02:00
commit 07a5adc8e0
5 files changed
+31 -27

No files matched your search

+1 -1
View File
@@ -506,7 +506,7 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_audioInit(JNIEnv *, jclass) {
ILOG("NativeApp.audioInit() -- Using OpenSL audio! frames/buffer: %i optimal sr: %i actual sr: %i", optimalFramesPerBuffer, optimalSampleRate, sampleRate);
if (!g_audioState) {
g_audioState = AndroidAudio_Init(&NativeMix, library_path, framesPerBuffer, sampleRate);
g_audioState = AndroidAudio_Init(&NativeMix, framesPerBuffer, sampleRate);
} else {
ELOG("Audio state already initialized");
}
+21 -16
View File
@@ -56,7 +56,9 @@ void OpenSLContext::BqPlayerCallback(SLAndroidSimpleBufferQueueItf bq) {
ELOG("OpenSL ES: Failed to enqueue! %i %i", renderedFrames, sizeInBytes);
}
curBuffer ^= 1; // Switch buffer
curBuffer += 1; // Switch buffer
if (curBuffer == NUM_BUFFERS)
curBuffer = 0;
}
// create the engine and output mix objects
@@ -83,7 +85,7 @@ bool OpenSLContext::Init() {
// The constants, such as SL_SAMPLINGRATE_44_1, are just 44100000.
SLuint32 sr = (SLuint32)sampleRate * 1000;
SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, NUM_BUFFERS};
SLDataFormat_PCM format_pcm = {
SL_DATAFORMAT_PCM,
2,
@@ -124,18 +126,20 @@ bool OpenSLContext::Init() {
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
assert(SL_RESULT_SUCCESS == result);
// Render and enqueue a first buffer. (or should we just play the buffer empty?)
buffer[0] = new short[framesPerBuffer * 2];
buffer[1] = new short[framesPerBuffer * 2];
// Allocate and enqueue N empty buffers.
for (int i = 0; i < NUM_BUFFERS; i++) {
buffer[i] = new short[framesPerBuffer * 2]{};
}
int sizeInBytes = framesPerBuffer * 2 * sizeof(short);
for (int i = 0; i < NUM_BUFFERS; i++) {
result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, buffer[i], sizeInBytes);
if (SL_RESULT_SUCCESS != result) {
return false;
}
}
curBuffer = 0;
audioCallback(buffer[curBuffer], framesPerBuffer);
result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, buffer[curBuffer], sizeof(buffer[curBuffer]));
if (SL_RESULT_SUCCESS != result) {
return false;
}
curBuffer ^= 1;
return true;
}
@@ -174,10 +178,11 @@ OpenSLContext::~OpenSLContext() {
engineObject = nullptr;
engineEngine = nullptr;
}
delete [] buffer[0];
delete [] buffer[1];
buffer[0] = nullptr;
buffer[1] = nullptr;
for (int i = 0; i < NUM_BUFFERS; i++) {
delete[] buffer[i];
buffer[i] = nullptr;
}
ILOG("OpenSLWrap_Shutdown - finished");
}
+7 -2
View File
@@ -37,10 +37,15 @@ private:
SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue = nullptr;
SLVolumeItf bqPlayerVolume = nullptr;
// Should be no reason to need more than two buffers, but make it clear in the code.
enum {
NUM_BUFFERS = 2,
};
// Double buffering.
short *buffer[2]{};
short *buffer[NUM_BUFFERS]{};
int curBuffer = 0;
static void bqPlayerCallbackWrap(SLAndroidSimpleBufferQueueItf bq, void *context);
void BqPlayerCallback(SLAndroidSimpleBufferQueueItf bq);
};
};
+1 -1
View File
@@ -9,7 +9,7 @@ struct AndroidAudioState {
int sample_rate = 0;
};
AndroidAudioState *AndroidAudio_Init(AndroidAudioCallback callback, std::string libraryDir, int optimalFramesPerBuffer, int optimalSampleRate) {
AndroidAudioState *AndroidAudio_Init(AndroidAudioCallback callback, int optimalFramesPerBuffer, int optimalSampleRate) {
AndroidAudioState *state = new AndroidAudioState();
state->callback = callback;
state->frames_per_buffer = optimalFramesPerBuffer ? optimalFramesPerBuffer : 256;
+1 -7
View File
@@ -5,14 +5,8 @@
struct AndroidAudioState;
// This is the file you should include from your program. It dynamically loads
// the native_audio.so shared object and sets up the function pointers.
// Do not call this if you have detected that the android version is below
// 2.2, as it will fail miserably.
// It's okay for optimalFramesPerBuffer and optimalSampleRate to be 0. Defaults will be used.
AndroidAudioState *AndroidAudio_Init(AndroidAudioCallback cb, std::string libraryDir, int optimalFramesPerBuffer, int optimalSampleRate);
AndroidAudioState *AndroidAudio_Init(AndroidAudioCallback cb, int optimalFramesPerBuffer, int optimalSampleRate);
bool AndroidAudio_Pause(AndroidAudioState *state);
bool AndroidAudio_Resume(AndroidAudioState *state);
bool AndroidAudio_Shutdown(AndroidAudioState *state);