Wip on using PlaybackRateItf for OpenSLES (note unfinished and makes client insta crash)

This commit is contained in:
UnknownShadow200 2021-08-23 18:46:01 +10:00
parent a3c328e6a9
commit ea424d84d5

View File

@ -517,31 +517,27 @@ static SLObjectItf slOutputObject;
struct AudioContext {
int count, channels, sampleRate;
SLObjectItf bqPlayerObject;
SLPlayItf bqPlayerPlayer;
SLBufferQueueItf bqPlayerQueue;
SLObjectItf playerObject;
SLPlayItf playerPlayer;
SLBufferQueueItf playerQueue;
SLPlaybackRateItf playerRate;
cc_uint32 _tmpSize; void* _tmpData;
};
static SLresult (SLAPIENTRY *_slCreateEngine)(
SLObjectItf *pEngine,
SLuint32 numOptions,
const SLEngineOption *pEngineOptions,
SLuint32 numInterfaces,
const SLInterfaceID *pInterfaceIds,
const SLboolean *pInterfaceRequired
);
static SLresult (SLAPIENTRY *_slCreateEngine)(SLObjectItf* engine, SLuint32 numOptions, const SLEngineOption* engineOptions,
SLuint32 numInterfaces, const SLInterfaceID* interfaceIds, const SLboolean* interfaceRequired);
static SLInterfaceID* _SL_IID_NULL;
static SLInterfaceID* _SL_IID_PLAY;
static SLInterfaceID* _SL_IID_ENGINE;
static SLInterfaceID* _SL_IID_BUFFERQUEUE;
static SLInterfaceID* _SL_IID_PLAYBACKRATE;
static const cc_string slLib = String_FromConst("libOpenSLES.so");
static cc_bool LoadSLFuncs(void) {
static const struct DynamicLibSym funcs[5] = {
DynamicLib_Sym(slCreateEngine), DynamicLib_Sym(SL_IID_NULL),
DynamicLib_Sym(SL_IID_PLAY), DynamicLib_Sym(SL_IID_ENGINE),
DynamicLib_Sym(SL_IID_BUFFERQUEUE)
static const struct DynamicLibSym funcs[] = {
DynamicLib_Sym(slCreateEngine), DynamicLib_Sym(SL_IID_NULL),
DynamicLib_Sym(SL_IID_PLAY), DynamicLib_Sym(SL_IID_ENGINE),
DynamicLib_Sym(SL_IID_BUFFERQUEUE), DynamicLib_Sym(SL_IID_PLAYBACKRATE)
};
void* lib = DynamicLib_Load2(&slLib);
@ -559,7 +555,8 @@ static cc_bool AudioBackend_Init(void) {
if (!LoadSLFuncs()) { Logger_WarnFunc(&msg); return false; }
/* mixer doesn't use any effects */
ids[0] = *_SL_IID_NULL; req[0] = SL_BOOLEAN_FALSE;
ids[0] = *_SL_IID_NULL;
req[0] = SL_BOOLEAN_FALSE;
res = _slCreateEngine(&slEngineObject, 0, NULL, 0, NULL, NULL);
if (res) { AudioWarn(res, "creating OpenSL ES engine"); return false; }
@ -596,20 +593,21 @@ void Audio_Init(struct AudioContext* ctx, int buffers) {
}
static void Audio_Stop(struct AudioContext* ctx) {
if (!ctx->bqPlayerPlayer) return;
if (!ctx->playerPlayer) return;
(*ctx->bqPlayerQueue)->Clear(ctx->bqPlayerQueue);
(*ctx->bqPlayerPlayer)->SetPlayState(ctx->bqPlayerPlayer, SL_PLAYSTATE_STOPPED);
(*ctx->playerQueue)->Clear(ctx->playerQueue);
(*ctx->playerPlayer)->SetPlayState(ctx->playerPlayer, SL_PLAYSTATE_STOPPED);
}
static void Audio_Reset(struct AudioContext* ctx) {
SLObjectItf bqPlayerObject = ctx->bqPlayerObject;
if (!bqPlayerObject) return;
SLObjectItf playerObject = ctx->playerObject;
if (!playerObject) return;
(*bqPlayerObject)->Destroy(bqPlayerObject);
ctx->bqPlayerObject = NULL;
ctx->bqPlayerPlayer = NULL;
ctx->bqPlayerQueue = NULL;
(*playerObject)->Destroy(playerObject);
ctx->playerObject = NULL;
ctx->playerPlayer = NULL;
ctx->playerQueue = NULL;
ctx->playerRate = NULL;
}
void Audio_Close(struct AudioContext* ctx) {
@ -621,10 +619,10 @@ void Audio_Close(struct AudioContext* ctx) {
cc_result Audio_SetFormat(struct AudioContext* ctx, int channels, int sampleRate) {
SLDataLocator_AndroidSimpleBufferQueue input;
SLDataLocator_OutputMix output;
SLObjectItf bqPlayerObject;
SLObjectItf playerObject;
SLDataFormat_PCM fmt;
SLInterfaceID ids[2];
SLboolean req[2];
SLInterfaceID ids[3];
SLboolean req[3];
SLDataSource src;
SLDataSink dst;
cc_result res;
@ -652,37 +650,39 @@ cc_result Audio_SetFormat(struct AudioContext* ctx, int channels, int sampleRate
dst.pLocator = &output;
dst.pFormat = NULL;
ids[0] = *_SL_IID_BUFFERQUEUE; req[0] = SL_BOOLEAN_TRUE;
ids[1] = *_SL_IID_PLAY; req[1] = SL_BOOLEAN_TRUE;
ids[0] = *_SL_IID_BUFFERQUEUE; req[0] = SL_BOOLEAN_TRUE;
ids[1] = *_SL_IID_PLAY; req[1] = SL_BOOLEAN_TRUE;
ids[2] = *_SL_IID_PLAYBACKRATE; req[2] = SL_BOOLEAN_TRUE;
res = (*slEngineEngine)->CreateAudioPlayer(slEngineEngine, &bqPlayerObject, &src, &dst, 2, ids, req);
ctx->bqPlayerObject = bqPlayerObject;
res = (*slEngineEngine)->CreateAudioPlayer(slEngineEngine, &playerObject, &src, &dst, 3, ids, req);
ctx->playerObject = playerObject;
if (res) return res;
if ((res = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE))) return res;
if ((res = (*bqPlayerObject)->GetInterface(bqPlayerObject, *_SL_IID_PLAY, &ctx->bqPlayerPlayer))) return res;
if ((res = (*bqPlayerObject)->GetInterface(bqPlayerObject, *_SL_IID_BUFFERQUEUE, &ctx->bqPlayerQueue))) return res;
if ((res = (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE))) return res;
if ((res = (*playerObject)->GetInterface(playerObject, *_SL_IID_PLAY, &ctx->playerPlayer))) return res;
if ((res = (*playerObject)->GetInterface(playerObject, *_SL_IID_BUFFERQUEUE, &ctx->playerQueue))) return res;
if ((res = (*playerObject)->GetInterface(playerObject, *_SL_IID_PLAYBACKRATE, &ctx->playerRate))) return res;
return 0;
}
cc_result Audio_QueueData(struct AudioContext* ctx, void* data, cc_uint32 size) {
return (*ctx->bqPlayerQueue)->Enqueue(ctx->bqPlayerQueue, data, size);
return (*ctx->playerQueue)->Enqueue(ctx->playerQueue, data, size);
}
static cc_result Audio_Pause(struct AudioContext* ctx) {
return (*ctx->bqPlayerPlayer)->SetPlayState(ctx->bqPlayerPlayer, SL_PLAYSTATE_PAUSED);
return (*ctx->playerPlayer)->SetPlayState(ctx->playerPlayer, SL_PLAYSTATE_PAUSED);
}
cc_result Audio_Play(struct AudioContext* ctx) {
return (*ctx->bqPlayerPlayer)->SetPlayState(ctx->bqPlayerPlayer, SL_PLAYSTATE_PLAYING);
return (*ctx->playerPlayer)->SetPlayState(ctx->playerPlayer, SL_PLAYSTATE_PLAYING);
}
cc_result Audio_Poll(struct AudioContext* ctx, int* inUse) {
SLBufferQueueState state = { 0 };
cc_result res = 0;
if (ctx->bqPlayerQueue) {
res = (*ctx->bqPlayerQueue)->GetState(ctx->bqPlayerQueue, &state);
if (ctx->playerQueue) {
res = (*ctx->playerQueue)->GetState(ctx->playerQueue, &state);
}
*inUse = state.count;
return res;
@ -695,10 +695,12 @@ cc_bool Audio_FastPlay(struct AudioContext* ctx, struct AudioData* data) {
}
cc_result Audio_PlayData(struct AudioContext* ctx, struct AudioData* data) {
cc_result res = 0;
cc_bool ok = AudioBase_AdjustSound(ctx, data);
if (!ok) return ERR_OUT_OF_MEMORY;
data->sampleRate = Audio_AdjustSampleRate(data);
/* rate is in milli, so 1000 = normal rate */
if ((res = (*ctx->playerRate)->SetRate(ctx->playerRate, data->rate * 10))) return res;
return AudioBase_PlaySound(ctx, data);
}