From 08d27dfd7b53717650d3f36ffd81a2c0c8e3cc8a Mon Sep 17 00:00:00 2001
From: Wohlstand <[EMAIL REDACTED]>
Date: Tue, 22 Feb 2022 15:27:30 +0300
Subject: [PATCH] SDL_openslES.c: Detect float support in runtime and use it
Allow using of the float output type on newer Android devices, but keep PCM16 output on older
Closes #5358
---
src/audio/openslES/SDL_openslES.c | 49 +++++++++++++++++++------------
1 file changed, 31 insertions(+), 18 deletions(-)
diff --git a/src/audio/openslES/SDL_openslES.c b/src/audio/openslES/SDL_openslES.c
index e0c732ba9a6..39d64b2b6aa 100644
--- a/src/audio/openslES/SDL_openslES.c
+++ b/src/audio/openslES/SDL_openslES.c
@@ -407,6 +407,7 @@ openslES_CreatePCMPlayer(_THIS)
{
struct SDL_PrivateAudioData *audiodata = this->hidden;
SLDataFormat_PCM format_pcm;
+ SLAndroidDataFormat_PCM_EX format_pcm_ex;
SLresult result;
int i;
@@ -414,30 +415,30 @@ openslES_CreatePCMPlayer(_THIS)
it can be done as described here:
https://developer.android.com/ndk/guides/audio/opensl/android-extensions.html#floating-point
*/
-#if 1
- /* Just go with signed 16-bit audio as it's the most compatible */
- this->spec.format = AUDIO_S16SYS;
-#else
- SDL_AudioFormat test_format;
- for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
- if (SDL_AUDIO_ISSIGNED(test_format) && SDL_AUDIO_ISINT(test_format)) {
- break;
+ if(SDL_GetAndroidSDKVersion() >= 21) {
+ SDL_AudioFormat test_format;
+ for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
+ if (SDL_AUDIO_ISSIGNED(test_format)) {
+ break;
+ }
}
- }
- if (!test_format) {
- /* Didn't find a compatible format : */
- LOGI( "No compatible audio format, using signed 16-bit audio" );
- test_format = AUDIO_S16SYS;
+ if (!test_format) {
+ /* Didn't find a compatible format : */
+ LOGI( "No compatible audio format, using signed 16-bit audio" );
+ test_format = AUDIO_S16SYS;
+ }
+ this->spec.format = test_format;
+ } else {
+ /* Just go with signed 16-bit audio as it's the most compatible */
+ this->spec.format = AUDIO_S16SYS;
}
- this->spec.format = test_format;
-#endif
/* Update the fragment size as size in bytes */
SDL_CalculateAudioSpec(&this->spec);
- LOGI("Try to open %u hz %u bit chan %u %s samples %u",
- this->spec.freq, SDL_AUDIO_BITSIZE(this->spec.format),
+ LOGI("Try to open %u hz %s %u bit chan %u %s samples %u",
+ this->spec.freq, SDL_AUDIO_ISFLOAT(this->spec.format) ? "float" : "pcm", SDL_AUDIO_BITSIZE(this->spec.format),
this->spec.channels, (this->spec.format & 0x1000) ? "BE" : "LE", this->spec.samples);
/* configure audio source */
@@ -488,7 +489,19 @@ openslES_CreatePCMPlayer(_THIS)
break;
}
- SLDataSource audioSrc = { &loc_bufq, &format_pcm };
+ if(SDL_AUDIO_ISFLOAT(this->spec.format)) {
+ /* Copy all setup into PCM EX structure */
+ format_pcm_ex.formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
+ format_pcm_ex.endianness = format_pcm.endianness;
+ format_pcm_ex.channelMask = format_pcm.channelMask;
+ format_pcm_ex.numChannels = format_pcm.numChannels;
+ format_pcm_ex.sampleRate = format_pcm.samplesPerSec;
+ format_pcm_ex.bitsPerSample = format_pcm.bitsPerSample;
+ format_pcm_ex.containerSize = format_pcm.containerSize;
+ format_pcm_ex.representation = SL_ANDROID_PCM_REPRESENTATION_FLOAT;
+ }
+
+ SLDataSource audioSrc = { &loc_bufq, SDL_AUDIO_ISFLOAT(this->spec.format) ? (void*)&format_pcm_ex : (void*)&format_pcm };
/* configure audio sink */
SLDataLocator_OutputMix loc_outmix = { SL_DATALOCATOR_OUTPUTMIX, outputMixObject };