mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-13 17:49:29 +01:00
Merge pull request #12333 from hrydgard/android-opensl-init-fix
Android OpenSL initial queue fix
This commit is contained in:
5 files changed
+31
-27
No files matched your search
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
};
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
Reference in new issue
Block a user