Compatibility hack for apps that ignore audio buffer size that SDL gives them

This commit is contained in:
pelya
2012-11-25 19:21:26 +02:00
parent 4dba58f168
commit bf150ecddb
3 changed files with 66 additions and 7 deletions

View File

@@ -285,6 +285,16 @@ if [ -n "$var" ] ; then
fi
fi
if [ -z "$CompatibilityHacksAppIgnoresAudioBufferSize" -o -z "$AUTO" ]; then
echo
echo -n "Hack for broken apps: application ignores audio buffer size returned by SDL (y)/(n) ($CompatibilityHacksAppIgnoresAudioBufferSize): "
read var
if [ -n "$var" ] ; then
CompatibilityHacksAppIgnoresAudioBufferSize="$var"
CHANGED=1
fi
fi
if [ -z "$AppUsesJoystick" -o -z "$AUTO" ]; then
echo
echo "Application uses joystick (y) or (n), the on-screen DPAD will be used"
@@ -651,6 +661,7 @@ echo CompatibilityHacks=$CompatibilityHacks >> AndroidAppSettings.cfg
echo CompatibilityHacksStaticInit=$CompatibilityHacksStaticInit >> AndroidAppSettings.cfg
echo CompatibilityHacksTextInputEmulatesHwKeyboard=$CompatibilityHacksTextInputEmulatesHwKeyboard >> AndroidAppSettings.cfg
echo CompatibilityHacksPreventAudioChopping=$CompatibilityHacksPreventAudioChopping >> AndroidAppSettings.cfg
echo CompatibilityHacksAppIgnoresAudioBufferSize=$CompatibilityHacksAppIgnoresAudioBufferSize >> AndroidAppSettings.cfg
echo AppUsesMouse=$AppUsesMouse >> AndroidAppSettings.cfg
echo AppNeedsTwoButtonMouse=$AppNeedsTwoButtonMouse >> AndroidAppSettings.cfg
echo ShowMouseCursor=$ShowMouseCursor >> AndroidAppSettings.cfg
@@ -772,6 +783,12 @@ else
CompatibilityHacksPreventAudioChopping=
fi
if [ "$CompatibilityHacksAppIgnoresAudioBufferSize" = "y" ] ; then
CompatibilityHacksAppIgnoresAudioBufferSize=-DSDL_AUDIO_APP_IGNORES_RETURNED_BUFFER_SIZE=1
else
CompatibilityHacksAppIgnoresAudioBufferSize=
fi
if [ "$AppUsesMouse" = "y" ] ; then
AppUsesMouse=true
else
@@ -983,7 +1000,7 @@ cat project/jni/SettingsTemplate.mk | \
sed "s^COMPILED_LIBRARIES := .*^COMPILED_LIBRARIES := $CompiledLibraries^" | \
sed "s^APPLICATION_ADDITIONAL_CFLAGS :=.*^APPLICATION_ADDITIONAL_CFLAGS := $AppCflags^" | \
sed "s^APPLICATION_ADDITIONAL_LDFLAGS :=.*^APPLICATION_ADDITIONAL_LDFLAGS := $AppLdflags^" | \
sed "s^SDL_ADDITIONAL_CFLAGS :=.*^SDL_ADDITIONAL_CFLAGS := $RedefinedKeycodes $RedefinedKeycodesScreenKb $CompatibilityHacksPreventAudioChopping^" | \
sed "s^SDL_ADDITIONAL_CFLAGS :=.*^SDL_ADDITIONAL_CFLAGS := $RedefinedKeycodes $RedefinedKeycodesScreenKb $CompatibilityHacksPreventAudioChopping $CompatibilityHacksAppIgnoresAudioBufferSize^" | \
sed "s^APPLICATION_SUBDIRS_BUILD :=.*^APPLICATION_SUBDIRS_BUILD := $AppSubdirsBuild^" | \
sed "s^APPLICATION_CUSTOM_BUILD_SCRIPT :=.*^APPLICATION_CUSTOM_BUILD_SCRIPT := $CustomBuildScript^" | \
sed "s^SDL_VERSION :=.*^SDL_VERSION := $LibSdlVersion^" >> \

View File

@@ -17,6 +17,7 @@ CompatibilityHacks=n
CompatibilityHacksStaticInit=n
CompatibilityHacksTextInputEmulatesHwKeyboard=n
CompatibilityHacksPreventAudioChopping=n
CompatibilityHacksAppIgnoresAudioBufferSize=n
AppUsesMouse=n
AppNeedsTwoButtonMouse=n
ShowMouseCursor=n

View File

@@ -38,6 +38,8 @@
#include <string.h> // for memset()
#include <pthread.h>
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define _THIS SDL_AudioDevice *this
/* Audio driver functions */
@@ -131,6 +133,9 @@ AudioBootStrap ANDROIDAUD_bootstrap = {
static unsigned char * audioBuffer = NULL;
static size_t audioBufferSize = 0;
static Uint32 audioLastTick = 0;
static unsigned char * shadowAppBuffer = NULL;
static Uint32 shadowAppBufferPos = 0;
static Uint32 shadowAppBufferSize = 0;
// Extremely wicked JNI environment to call Java functions from C code
static jbyteArray audioBufferJNI = NULL;
@@ -144,7 +149,11 @@ static jmethodID JavaResumeAudioPlayback = NULL;
static Uint8 *ANDROIDAUD_GetAudioBuf(_THIS)
{
#ifdef SDL_AUDIO_APP_IGNORES_RETURNED_BUFFER_SIZE
return(shadowAppBuffer);
#else
return(audioBuffer);
#endif
}
@@ -176,7 +185,7 @@ static int ANDROIDAUD_OpenAudio (_THIS, SDL_AudioSpec *spec)
__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_OpenAudio(): app requested audio bytespersample %d freq %d channels %d samples %d", bytesPerSample, audioFormat->freq, (int)audioFormat->channels, (int)audioFormat->samples);
if(audioFormat->samples <= 0)
audioFormat->samples = 128; // Some sane value
audioFormat->samples = 16; // Some sane value
if( audioFormat->samples > 32768 ) // Why anyone need so huge audio buffer?
{
audioFormat->samples = 32768;
@@ -185,7 +194,6 @@ static int ANDROIDAUD_OpenAudio (_THIS, SDL_AudioSpec *spec)
SDL_CalculateAudioSpec(audioFormat);
(*jniVM)->AttachCurrentThread(jniVM, &jniEnv, NULL);
if( !jniEnv )
@@ -209,12 +217,20 @@ static int ANDROIDAUD_OpenAudio (_THIS, SDL_AudioSpec *spec)
/* We cannot call DetachCurrentThread() from main thread or we'll crash */
/* (*jniVM)->DetachCurrentThread(jniVM); */
#ifdef SDL_AUDIO_APP_IGNORES_RETURNED_BUFFER_SIZE
shadowAppBufferSize = audioFormat->size;
shadowAppBuffer = malloc(shadowAppBufferSize);
shadowAppBufferPos = 0;
if( shadowAppBufferSize > audioBufferSize )
__android_log_print(ANDROID_LOG_FATAL, "libSDL", "ANDROIDAUD_OpenAudio(): Java returned audio buffer smaller than app requested, SDL will crash!");
#else
audioFormat->samples = audioBufferSize / bytesPerSample / audioFormat->channels;
audioFormat->size = audioBufferSize;
__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_OpenAudio(): app opened audio bytespersample %d freq %d channels %d bufsize %d", bytesPerSample, audioFormat->freq, (int)audioFormat->channels, audioBufferSize);
#endif
SDL_CalculateAudioSpec(audioFormat);
__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_OpenAudio(): app opened audio bytespersample %d freq %d channels %d bufsize %d, SDL returns bufsize %d", bytesPerSample, audioFormat->freq, (int)audioFormat->channels, audioBufferSize, audioFormat->size);
#if SDL_VERSION_ATLEAST(1,3,0)
return(1);
#else
@@ -232,7 +248,10 @@ static void ANDROIDAUD_CloseAudio(_THIS)
audioBufferJNI = NULL;
audioBuffer = NULL;
audioBufferSize = 0;
#ifdef SDL_AUDIO_APP_IGNORES_RETURNED_BUFFER_SIZE
free(shadowAppBuffer);
shadowAppBuffer = NULL;
#endif
(*jniEnv)->CallIntMethod( jniEnv, JavaAudioThread, JavaDeinitAudio );
/* We cannot call DetachCurrentThread() from main thread or we'll crash */
@@ -300,7 +319,7 @@ static void ANDROIDAUD_ThreadDeinit(_THIS)
(*jniVM)->DetachCurrentThread(jniVM);
};
static void ANDROIDAUD_PlayAudio(_THIS)
static void ANDROIDAUD_SendAudioToJava(void)
{
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_PlayAudio()");
jboolean isCopy = JNI_TRUE;
@@ -318,6 +337,28 @@ static void ANDROIDAUD_PlayAudio(_THIS)
__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_PlayAudio() JNI returns a copy of byte array - that's slow");
}
#ifdef SDL_AUDIO_APP_IGNORES_RETURNED_BUFFER_SIZE
static void ANDROIDAUD_PlayAudio(_THIS)
{
int audioCopiedSize = MIN(shadowAppBufferSize, audioBufferSize - shadowAppBufferPos);
memcpy(audioBuffer + shadowAppBufferPos, shadowAppBuffer, audioCopiedSize);
shadowAppBufferPos += audioCopiedSize;
if( shadowAppBufferPos >= audioBufferSize )
{
ANDROIDAUD_SendAudioToJava();
int audioCopiedRemaining = shadowAppBufferSize - audioCopiedSize;
memcpy(audioBuffer, shadowAppBuffer + audioCopiedSize, audioCopiedRemaining);
shadowAppBufferPos = audioCopiedRemaining;
}
}
#else
static void ANDROIDAUD_PlayAudio(_THIS)
{
ANDROIDAUD_SendAudioToJava();
}
#endif
int SDL_ANDROID_PauseAudioPlayback(void)
{
JNIEnv * jniEnv = NULL;