SF2 custom modulators#2355
Merged
Merged
Conversation
2d76754 to
a29fb86
Compare
Parse SF2 modulator chunks (pmod/imod) and store on SF2Zone. Full modulator evaluation per SF2 spec 9.5.3: source extraction (velocity, key, CC, pitch wheel), transform curves (concave/convex/switch, unipolar/bipolar), two-source multiplication, absolute value transform. All 10 default modulators from SF2 spec 8.4.1-8.4.10 with zone override logic. Replaces hardcoded velocity curve. Parsing: - SF2Modulator struct, parse_modulators for pmod/imod chunks (10 bytes/entry) - Source unpacking: sf2_mod_src_index/cc/negative/bipolar/type - Modulators stored on SF2Zone alongside generators Evaluation: - sf2_concave/sf2_convex: SF2 spec page 73 transform curves - sf2_mod_source_value: velocity, key, CC, pitch wheel, pitch wheel sensitivity - sf2_mod_transform_source: unipolar/bipolar, positive/negative, all 4 map types - sf2_mod_get_value: amount * transform(src1) * transform(src2), abs transform - sf2_apply_modulators: accumulate per-generator offsets from zone modulators Default modulators: - SF2_DEFAULT_MODS: 10 defaults (vel->atten, vel->filter, pressure->vib, CC1->vib, CC7->atten, CC10->pan, CC11->atten, CC91->reverb, CC93->chorus, pitchwheel->tune) - sf2_mod_identity_match + sf2_apply_default_modulators with override logic - Removed hardcoded sf2_velocity_attenuation (now handled by default mod #1) Application in sf2_create_c_voice: - Compute gen_offsets[64] from zone + global + preset modulators + defaults - Apply offsets to pitch, filter FC/Q, attenuation, pan, all LFO/env routing Also: midi_init_reverb() public function for offline rendering with reverb 20 new tests: source unpacking, evaluation (6 cases), parse counts (FluidR3=746, TimGM6mb=455), voice velocity dynamics, default mod dynamics, override logic Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
a29fb86 to
a7bfe94
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
SF2Zone.modulatorsalongside generatorsmidi_init_reverb()— public function for offline rendering with reverbAudible improvement confirmed: GeneralUser GS (2445 modulators) renders with near-zero correlation to non-modulated version. Musyng Kite shows peak diff of 2.0 (full range). All three tested SF2 fonts produce measurably different (better) output.
Files changed
strudel_sf2.dasSF2Modulatorstruct, source unpacking helpers,parse_modulators, modulators onSF2Zonestrudel_sf2_voice.dassf2_mod_get_value,sf2_apply_modulators, 10 default modulators with override logic, modulator offsets insf2_create_c_voicestrudel_midi_player.dasmidi_init_reverb()public functiontest_sf2_modulators.dasTest plan