Skip to content

Support SF3 soundfonts, update TinySoundFont, add tests and CI - #6

Merged
lemcoder merged 3 commits into
masterfrom
feat/sf3-support
Nov 4, 2026
Merged

lemcoder merged 3 commits into
masterfrom
feat/sf3-support

Conversation

@lemcoder

@lemcoder lemcoder commented Nov 4, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • SF3 support. Vendors stb_vorbis v1.22 (native/src/stb_vorbis.c, compiled as its own translation unit). tsf.c includes its declarations before tsf.h, which turns on TinySoundFont's existing SF3 code path: Ogg Vorbis compressed samples are decoded when the font loads. No API change; MikroSoundFont.load accepts .sf3 bytes on every platform.

  • TinySoundFont updated to current upstream (2025): sustain pedal (MIDI CC 64), note-on with velocity 0 acts as note-off, LIMITATTN unit fix, realloc and struct packing fixes. tsfCInterop.h gains tsf_channel_set_sustain.

  • Channel.setSustain(Boolean) exposes the new sustain call on Android and Kotlin/Native. setMidiControl(64, …) reaches it as well.

  • README documents SF3: samples are decoded up front (slower load, several times the file size in memory), and stb_vorbis isn't hardened against malformed input, so only trusted .sf3 files should be loaded.

  • Tests and CI. First test suite: commonTest runs every case against an SF2 fixture (TinySoundFont's florestan-subset.sf2) and an SF3 made from it (scripts/make-test-sf3.py): presets, rendering, stereo pan, sustain pedal, close(), rejecting non-SoundFont data. Runs natively on the host (linuxX64Test, macosArm64Test) and on a device (connectedAndroidDeviceTest). New Test workflow runs linuxX64Test on PRs and master pushes, no emulator needed. gradlew is now executable in git.

Supersedes #2, which proposed SF3 via stb_vorbis on the old CMake/JNI build; thanks to @Von-Cheam for raising it.

Test plan

  • ./gradlew assemble for all targets
  • macosArm64Test: 11/11
  • connectedAndroidDeviceTest on SM-S948B (Android 17): 11/11
  • CI linuxX64Test: green (~2 min)
  • Mutation check: disabling sustain and pan in the native delegate fails 4 tests
  • Large real-world SF3 (FluidR3Mono_GM, 23 MB): 197 presets, renders on macOS and the device (~18 s load on the phone)
  • arm64-v8a and x86_64 libtinySoundFontstubs.so still 16 KB aligned (65 KB → 150 KB)
  • iosSimulatorArm64Test: not run, no simulator runtime installed locally

🤖 Generated with Claude Code

lemcoder and others added 3 commits November 4, 2026 20:33
Vendor stb_vorbis v1.22 as its own translation unit and include its
declarations ahead of tsf.h, which turns on TinySoundFont's existing SF3
(Ogg Vorbis compressed samples) path. Update tsf.h to upstream (2025):
sustain pedal (MIDI CC 64) and tsf_channel_set_sustain, velocity 0
note-on as note-off, LIMITATTN unit fix, realloc and packing fixes.

The README notes that SF3 samples are decoded at load time and that
stb_vorbis should only be fed trusted files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Exposes TinySoundFont's tsf_channel_set_sustain: while held, noteOff keeps
notes sounding until the pedal is released.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
commonTest loads an SF2 fixture (TinySoundFont's florestan-subset) and an
SF3 made from it by scripts/make-test-sf3.py, then checks presets,
rendering, stereo panning, the sustain pedal, close() and rejection of
non-SoundFont data. They run natively on the host (linuxX64Test,
macosArm64Test; the fixtures path comes from an environment variable)
and on a device via connectedAndroidDeviceTest.

The Test workflow runs linuxX64Test on pull requests and pushes to
master, which exercises the same native code without an Android emulator.
gradlew is now executable in git.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@lemcoder lemcoder changed the title Support SF3 soundfonts, update TinySoundFont, add Channel.setSustain Support SF3 soundfonts, update TinySoundFont, add tests and CI Nov 4, 2026
@lemcoder
lemcoder merged commit 3511069 into master Nov 4, 2026
1 check passed
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