At long last, music works on android

This commit is contained in:
UnknownShadow200 2020-10-23 20:57:03 +11:00
parent fa687f1e93
commit 9688c2ebd2

View File

@ -380,6 +380,7 @@ static SLObjectItf slOutputObject;
struct AudioContext { struct AudioContext {
struct AudioFormat format; struct AudioFormat format;
int count; int count;
cc_bool available[AUDIO_MAX_BUFFERS];
SLObjectItf bqPlayerObject; SLObjectItf bqPlayerObject;
SLPlayItf bqPlayerPlayer; SLPlayItf bqPlayerPlayer;
SLBufferQueueItf bqPlayerQueue; SLBufferQueueItf bqPlayerQueue;
@ -425,6 +426,10 @@ static void Backend_Free(void) {
} }
void Audio_Init(struct AudioContext* ctx, int buffers) { void Audio_Init(struct AudioContext* ctx, int buffers) {
int i;
for (i = 0; i < buffers; i++) {
ctx->available[i] = true;
}
ctx->count = buffers; ctx->count = buffers;
} }
@ -434,10 +439,23 @@ static cc_result Backend_Reset(struct AudioContext* ctx) {
(*bqPlayerObject)->Destroy(bqPlayerObject); (*bqPlayerObject)->Destroy(bqPlayerObject);
ctx->bqPlayerObject = NULL; ctx->bqPlayerObject = NULL;
ctx->bqPlayerPlayer = NULL; ctx->bqPlayerPlayer = NULL;
ctx->bqPlayerQueue = NULL;
} }
return 0; return 0;
} }
static void OnBufferFinished(SLBufferQueueItf bq, void* context) {
struct AudioContext* ctx = (struct AudioContext*)context;
SLBufferQueueState state = { 0 };
unsigned int i;
if ((*ctx->bqPlayerQueue)->GetState(ctx->bqPlayerQueue, &state)) return;
/* At this point, playIndex is for index of NEXT buffer (about to be played) */
/* So need to subtract 1 from it */
i = (state.playIndex - 1) % (unsigned int)ctx->count;
ctx->available[i] = true;
}
static cc_result Backend_SetFormat(struct AudioContext* ctx, struct AudioFormat* format) { static cc_result Backend_SetFormat(struct AudioContext* ctx, struct AudioFormat* format) {
SLDataLocator_AndroidSimpleBufferQueue input; SLDataLocator_AndroidSimpleBufferQueue input;
SLDataLocator_OutputMix output; SLDataLocator_OutputMix output;
@ -454,7 +472,7 @@ static cc_result Backend_SetFormat(struct AudioContext* ctx, struct AudioFormat*
fmt.samplesPerSec = format->sampleRate * 1000; fmt.samplesPerSec = format->sampleRate * 1000;
fmt.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16; fmt.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
fmt.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16; fmt.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16;
fmt.channelMask = SL_SPEAKER_FRONT_CENTER; fmt.channelMask = 0;
fmt.endianness = SL_BYTEORDER_LITTLEENDIAN; fmt.endianness = SL_BYTEORDER_LITTLEENDIAN;
input.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE; input.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
@ -477,10 +495,12 @@ static cc_result Backend_SetFormat(struct AudioContext* ctx, struct AudioFormat*
if ((res = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE))) 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_PLAY, &ctx->bqPlayerPlayer))) return res;
if ((res = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_BUFFERQUEUE, &ctx->bqPlayerQueue))) return res; if ((res = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_BUFFERQUEUE, &ctx->bqPlayerQueue))) return res;
return 0;
return (*ctx->bqPlayerQueue)->RegisterCallback(ctx->bqPlayerQueue, OnBufferFinished, ctx);
} }
cc_result Audio_BufferData(struct AudioContext* ctx, int idx, void* data, cc_uint32 size) { cc_result Audio_BufferData(struct AudioContext* ctx, int idx, void* data, cc_uint32 size) {
ctx->available[idx] = false;
return (*ctx->bqPlayerQueue)->Enqueue(ctx->bqPlayerQueue, data, size); return (*ctx->bqPlayerQueue)->Enqueue(ctx->bqPlayerQueue, data, size);
} }
@ -489,18 +509,26 @@ cc_result Audio_Play(struct AudioContext* ctx) {
} }
cc_result Audio_Stop(struct AudioContext* ctx) { cc_result Audio_Stop(struct AudioContext* ctx) {
if (!ctx->bqPlayerPlayer) return 0;
return (*ctx->bqPlayerPlayer)->SetPlayState(ctx->bqPlayerPlayer, SL_PLAYSTATE_STOPPED); return (*ctx->bqPlayerPlayer)->SetPlayState(ctx->bqPlayerPlayer, SL_PLAYSTATE_STOPPED);
} }
cc_result Audio_IsAvailable(struct AudioContext* ctx, int idx, cc_bool* available) { cc_result Audio_IsAvailable(struct AudioContext* ctx, int idx, cc_bool* available) {
/* TODO: This is completely WRONG! Might work for sounds but not music.. */ *available = ctx->available[idx];
return Audio_IsFinished(ctx, available); return 0;
} }
cc_result Audio_IsFinished(struct AudioContext* ctx, cc_bool* finished) { cc_result Audio_IsFinished(struct AudioContext* ctx, cc_bool* finished) {
SLBufferQueueState state = { 0 }; SLBufferQueueState state = { 0 };
cc_result res = (*ctx->bqPlayerQueue)->GetState(ctx->bqPlayerQueue, &state); cc_result res;
*finished = state.count == 0;
if (ctx->bqPlayerQueue) {
res = (*ctx->bqPlayerQueue)->GetState(ctx->bqPlayerQueue, &state);
*finished = state.count == 0;
} else {
res = 0;
*finished = true;
}
return res; return res;
} }
#endif #endif