Skip to content

Add SF3 (OGG Vorbis compressed) SoundFont support and Android 15+ compatibilty via 16KB ELF page alignment#2

Open
Von-Cheam wants to merge 1 commit intolemcoder:masterfrom
Von-Cheam:feature/sf3-support
Open

Add SF3 (OGG Vorbis compressed) SoundFont support and Android 15+ compatibilty via 16KB ELF page alignment#2
Von-Cheam wants to merge 1 commit intolemcoder:masterfrom
Von-Cheam:feature/sf3-support

Conversation

@Von-Cheam
Copy link
Copy Markdown

@Von-Cheam Von-Cheam commented Mar 28, 2026

Summary

This PR, which was generated with the use of AI, adds two independent features to MikroSoundFont's Android native library:

  1. SF3 (OGG Vorbis) SoundFont support — enables transparent loading of .sf3 SoundFont files (which use OGG Vorbis compression for sample data) alongside existing .sf2 support
  2. 16KB ELF page alignment — fixes compatibility with Android 15+ devices that use 16KB memory page sizes (see https://developer.android.com/guide/practices/page-sizes)

SF3 Support

SF3 is an extension of the SF2 format where sample data is compressed with OGG Vorbis, typically reducing file sizes by 5–10×. The SF3 format is widely used (e.g., by MuseScore's default SoundFonts) and is structurally identical to SF2 except for the sample encoding.

Changes

  • native/src/stb_vorbis.c (new file): Sean Barrett's stb_vorbis public-domain OGG Vorbis decoder. This is a single-file, header-only C library with no external dependencies
  • native/src/tsf.c: Added #include "stb_vorbis.c" before the TinySoundFont include, which enables the TSF_SUPPORT_OGG compile-time path already present in tsf.h, specifically tsf_decode_ogg() and tsf_decode_sf3_samples(), which detect SF3 compression flags in SoundFont shdr records and decode OGG-compressed samples at load time
  • soundfont/src/androidMain/cpp/mikro_sound_font_jni.c: Added matching #include "stb_vorbis.c" in the JNI layer

The Kotlin API is unchanged — MikroSoundFont.loadSoundFont(ByteArray) handles SF3 files transparently, as the format detection and decompression happen entirely in the C layer.

Testing

Tested with:

  • Standard .sf2 files (regression — no change in behaviour)
  • FluidR3Mono_GM .sf3 file (197 presets, successful load and playback)

16KB ELF Page Alignment

Android 15+ (API 35+) requires support for devices with 16KB memory page sizes. Native .so library files must have their ELF LOAD segments aligned to 16KB boundaries on these devices, or the app displays a compatibility warning dialog on every launch and cannot be distributed via to Google Play.

The current release (v0.3.0) builds libmikroSoundFontJNI.so with the default 4KB LOAD segment alignment, which blocks distribution via Google Play and triggers the following runtime warning on Android 15+ devices:

This app isn't 16 KB compatible. ELF alignment check failed.
The following libraries are not 16 KB aligned:
• lib/x86_64/libmikroSoundFontJNI.so : LOAD segment not aligned

Changes

  • soundfont/src/androidMain/cpp/CMakeLists.txt: Added target_link_options(mikroSoundFontJNI PRIVATE "-Wl,-z,max-page-size=16384"), which instructs the linker to align LOAD segments to 16KB boundaries

The resulting .so is backwards-compatible with 4KB page-size devices — 16KB alignment is a superset of 4KB alignment, so no conditional compilation or separate builds are needed.

AI

Claude Opus 4.6, via Claude Code, was used to implement the features added in this PR. All changes made were reviewed, and all testing carried-out, by a human.

Build Changes

  • gradle/libs.versions.toml: Version updated to 0.3.0-sf3 to distinguish from the upstream release
  • settings.gradle.kts: Minor build configuration updates
  • soundfont/build.gradle.kts: Build configuration updates for the native compilation pipeline

SF3 support: include stb_vorbis.c in native build and JNI layer, enabling transparent loading of SF3 (OGG Vorbis compressed) SoundFont files alongside existing SF2 support.

16KB alignment: add -Wl,-z,max-page-size=16384 linker flag to CMakeLists.txt so the built .so passes Android 15+ 16KB page size requirements (). The resulting binary is backwards-compatible with 4KB devices.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant