Fix SFX and MIDI music not playing on Android
snd_start_digital() opened two separate SDL audio devices - a raw one for cutscene/audiolog audio and a second via Mix_OpenAudio() for SFX/MIDI - but Android's audio backends only ever allow one open non-capture device, so the second open always failed silently. - Consolidate onto a single Mix_OpenAudio() device; cutscene/audiolog PCM is now mixed into its output via Mix_SetPostMix() instead of a dedicated device (16-android-audio-single-device.patch) - Add SDL_GetError() to the failure log so a future open failure is actually diagnosable (15-android-audio-error-detail.patch) - Make NativeMidiInit() report failure on platforms with no real implementation (Android included), instead of silently claiming success without opening anything (17-android-native-midi-unsupported.patch) - Strengthen the OpenSL ES driver hint to SDL_HINT_OVERRIDE and log the active audio driver as a standing diagnostic (05-android-audio-driver.patch)
This commit is contained in:
@@ -383,10 +383,14 @@ each one does:
|
||||
emulation) for real GLES-native equivalents: a custom `pointSize`
|
||||
uniform, a shader-side alpha discard, and native point-sprite
|
||||
rasterization.
|
||||
- **`05-android-audio-driver.patch`** - forces SDL2's older OpenSL ES
|
||||
audio backend instead of AAudio, because AAudio only allows one open
|
||||
playback device and the engine opens two (cutscene audio plus
|
||||
`Mix_OpenAudio` for SFX/MIDI).
|
||||
- **`05-android-audio-driver.patch`** - forces SDL2's OpenSL ES audio
|
||||
backend instead of AAudio via
|
||||
`SDL_SetHintWithPriority(..., SDL_HINT_OVERRIDE)` (so nothing else can
|
||||
take precedence and silently leave AAudio selected), and logs the
|
||||
actual `SDL_GetCurrentAudioDriver()` result right after `SDL_Init()`
|
||||
as a standing on-device diagnostic. Does not by itself fix SFX/MIDI
|
||||
playback - see `16-android-audio-single-device.patch` and README 5.5.3
|
||||
for the actual cause and fix.
|
||||
- **`06-android-resize-event.patch`** - makes the engine react to
|
||||
`SDL_WINDOWEVENT_RESIZED`, not just `SIZE_CHANGED`, since Android's SDL
|
||||
backend only ever sends the former for surface-driven resizes.
|
||||
@@ -434,6 +438,32 @@ each one does:
|
||||
inherited non-default unpack state left behind elsewhere in the frame
|
||||
and misread every row. Fixed by resetting both to the packed defaults
|
||||
immediately before this upload.
|
||||
- **`15-android-audio-error-detail.patch`** - `snd_start_digital()`'s
|
||||
`Mix_OpenAudio()` failure only logged a fixed string, not the actual
|
||||
reason. Adds `SDL_GetError()` to the log line so the next on-device
|
||||
failure reports the real underlying error.
|
||||
- **`16-android-audio-single-device.patch`** - fixes SFX/MIDI music not
|
||||
playing (see README 5.5.3). `snd_start_digital()` opened two SDL audio
|
||||
devices: a raw `SDL_OpenAudioDevice()` for cutscene/audiolog audio and
|
||||
a second one via `Mix_OpenAudio()` for SFX/MIDI - SDL's Android audio
|
||||
backends only ever allow one open non-capture device, so the second
|
||||
open always failed. Removes the raw device entirely and feeds cutscene/
|
||||
audiolog PCM into the `Mix_OpenAudio()` device's output instead, via
|
||||
`Mix_SetPostMix()` (mixing in rather than overwriting, so it doesn't
|
||||
silence any SFX/MIDI music playing at the same time). `cutsloop.c`'s
|
||||
and `audiolog.c`'s `SDL_PauseAudioDevice()` calls (no longer meaningful
|
||||
without a dedicated device) are removed; the cutscene-audio-stream
|
||||
pointer swaps they guarded are now protected by `SDL_LockAudio()`/
|
||||
`SDL_UnlockAudio()` instead, since SDL_mixer's audio thread now reads
|
||||
that pointer continuously via the post-mix hook.
|
||||
- **`17-android-native-midi-unsupported.patch`** - `NativeMidiInit()` in
|
||||
`MusicDevice.c` has real implementations only under `#ifdef WIN32` and
|
||||
`#elif defined(USE_ALSA)`; on every other platform (Android included)
|
||||
it fell through to `return 0` (success) without ever opening a device,
|
||||
so a `midi-backend` preference of "Native" (see README 5.5.4) played
|
||||
silently forever instead of falling back. Adds an `#else` branch that
|
||||
returns failure and logs a `WARN`, so `InitDecXMI()`'s existing
|
||||
fallback-to-dummy-driver logic actually triggers.
|
||||
|
||||
`android/gl4es-patches/`:
|
||||
|
||||
@@ -517,10 +547,58 @@ left behind elsewhere in the frame and misreads every row - a diagonal
|
||||
shear/banding pattern. Menus never trigger it because nothing in the
|
||||
menu-only code paths sets a custom unpack stride first.
|
||||
|
||||
**Fix** (`14-android-quad-unpack-state.patch`): explicitly reset both
|
||||
`GL_UNPACK_ROW_LENGTH` and `GL_UNPACK_ALIGNMENT` to their tightly-packed
|
||||
values immediately before this `glTexImage2D` call, removing the
|
||||
dependency on whatever GL state preceded it.
|
||||
#### 5.5.3. In-game SFX and MIDI music didn't play
|
||||
|
||||
Intro cutscene audio played correctly, but in-game SFX and MIDI/background
|
||||
music never played, on-device.
|
||||
|
||||
**Root cause:** `snd_start_digital()` in `engine/src/MacSrc/SDLSound.c`
|
||||
opened two separate SDL audio devices - a raw `SDL_OpenAudioDevice()`
|
||||
call (used for cutscene/movie audio, always succeeded) and a second
|
||||
device via `Mix_OpenAudio()` (used for SFX and, via `Mix_HookMusic`,
|
||||
MIDI music - always failed, `SDL_GetError()` reporting "Audio device
|
||||
already open"). SDL's Android audio backends (both AAudio and OpenSL ES)
|
||||
only ever allow one open non-capture device - forcing OpenSL ES instead
|
||||
of AAudio (`05-android-audio-driver.patch`) doesn't change this, since
|
||||
the restriction isn't backend-specific.
|
||||
|
||||
**Fix (`16-android-audio-single-device.patch`):** removed the raw
|
||||
`SDL_OpenAudioDevice()` call entirely. Cutscene/audiolog PCM (previously
|
||||
delivered via that device's own callback) is now mixed into the single
|
||||
`Mix_OpenAudio()` device's output via `Mix_SetPostMix()`, additively
|
||||
(`SDL_MixAudioFormat`) rather than overwritten, so SFX/MIDI music
|
||||
already mixed into the buffer isn't silenced whenever a cutscene or
|
||||
audiolog plays. The stream-pointer swaps in `cutsloop.c`/`audiolog.c`
|
||||
that used to be guarded by pausing the now-removed device are guarded by
|
||||
`SDL_LockAudio()`/`SDL_UnlockAudio()` instead, since the post-mix hook
|
||||
runs continuously on SDL_mixer's own audio thread.
|
||||
|
||||
#### 5.5.4. MIDI music silent even after audio otherwise worked
|
||||
|
||||
After fixing 5.5.3, SFX and cutscene audio played correctly, but MIDI
|
||||
background music was still silent, with logcat showing `Creating native
|
||||
MIDI device` instead of `Creating FluidSynth MIDI device`.
|
||||
|
||||
**Root cause:** the engine's `midi-backend` preference (`0` = ADLMIDI,
|
||||
`1` = Native, `2` = FluidSynth) is persisted in a `prefs.txt` file in the
|
||||
app's private storage, which Android retains across every APK
|
||||
reinstall/upgrade (only a full uninstall clears it). A stale value of
|
||||
`1` (Native) from earlier testing was carried forward through every
|
||||
rebuild this whole session. `SetDefaultPrefs()` (`Prefs.c`) does default
|
||||
to `2` (FluidSynth) whenever `USE_FLUIDSYNTH` is defined, which it
|
||||
always has been for this build - the default was never wrong, only the
|
||||
persisted override. `NativeMidiInit()` has no real implementation on
|
||||
Android (see `17-android-native-midi-unsupported.patch`), so it silently
|
||||
reported success without opening anything.
|
||||
|
||||
**Fix:** a full uninstall (not just installing a new build over the old
|
||||
one) clears the stale preference, after which MIDI plays correctly.
|
||||
`17-android-native-midi-unsupported.patch` additionally makes
|
||||
`NativeMidiInit()` report failure on unsupported platforms, so a stale
|
||||
"Native" preference falls back to `InitDecXMI()`'s existing dummy-driver
|
||||
path (still silent, but with a clear `WARN` in logcat) instead of
|
||||
silently reporting success while never opening anything - a much faster
|
||||
diagnosis if this ever recurs.
|
||||
|
||||
## 6. License
|
||||
|
||||
|
||||
Reference in New Issue
Block a user