From 13470268e128e4997770d3fc3ceb87d4cb8d68eb Mon Sep 17 00:00:00 2001 From: Douglas Carmichael Date: Tue, 7 Jul 2026 17:58:12 -0400 Subject: [PATCH] SoundFont 2: skip "marker" presets that reference no samples Commercial SoundFonts frequently include one or two presets that carry no playable content and exist only to stamp the file with the vendor or copyright - e.g. an E-mu Orbit.SF2 has presets named "E-mu Systems 2007" and "DigitalSoundFactory", each with a preset zone pointing at an instrument that has no instrument zones (zero samples). The detector created an IMultisampleSource for every preset regardless, so these produced empty instruments in the destination format (e.g. an empty Waldorf QPAT, or an empty Renoise XRNI). Skip any preset whose multi-sample has no non-empty groups, mirroring the existing guard in the Ensoniq EPS/ASR detector, and log which preset was skipped. Verified on Orbit.SF2: 236 presets -> 234 written, the two marker presets skipped with a log line, all real presets unaffected. --- documentation/CHANGELOG.md | 2 ++ .../convertwithmoss/format/sf2/Sf2Detector.java | 11 +++++++++++ src/main/resources/Strings.properties | 1 + 3 files changed, 14 insertions(+) diff --git a/documentation/CHANGELOG.md b/documentation/CHANGELOG.md index 6d284df5..dd445918 100644 --- a/documentation/CHANGELOG.md +++ b/documentation/CHANGELOG.md @@ -35,6 +35,8 @@ * Omnisphere * Fixed: Reading an Omnisphere preset with multiple sample voice elements did only return the samples of the last voice. * Fixed: Save formatting of ampersand character when writing. +* SoundFont 2 (thanks to Douglas Carmichael) + * Fixed: "Marker" presets that reference no samples (commercial SoundFonts often include one or two named after the vendor or copyright, e.g. "E-mu Systems 2007") were converted into empty instruments. Presets without any samples are now skipped. * TX16W * Fixed: First check if the referenced absolute sample file path exists before searching all local folders. * Waldorf Quantum/Iridium (thanks to Douglas Carmichael) diff --git a/src/main/java/de/mossgrabers/convertwithmoss/format/sf2/Sf2Detector.java b/src/main/java/de/mossgrabers/convertwithmoss/format/sf2/Sf2Detector.java index 76aa76a9..b7ad71b6 100644 --- a/src/main/java/de/mossgrabers/convertwithmoss/format/sf2/Sf2Detector.java +++ b/src/main/java/de/mossgrabers/convertwithmoss/format/sf2/Sf2Detector.java @@ -140,6 +140,17 @@ private List parseSF2File (final File sourceFile, final Sf2F if (this.settingsConfiguration.addFileName () || this.settingsConfiguration.addProgramNumber ()) presetName = this.addPrefixes (presetName, preset.getProgramNumber (), FileUtils.getNameWithoutType (sourceFile)); final IMultisampleSource multisampleSource = this.createMultisampleSource (sourceFile, parts, presetName, this.combineToStereo (groups)); + + // Skip "empty" presets which reference no samples. Commercial SoundFonts often carry + // marker presets named after the vendor or the copyright (e.g. "E-mu Systems 2007") + // whose instrument has no zones; without this guard they would be written as empty + // instruments. + if (multisampleSource.getNonEmptyGroups (false).isEmpty ()) + { + this.notifier.log ("IDS_NOTIFY_SF2_SKIP_EMPTY_PRESET", presetName); + continue; + } + this.fillMetadata (sf2File, parts, multisampleSource.getMetadata ()); multisamples.add (multisampleSource); } diff --git a/src/main/resources/Strings.properties b/src/main/resources/Strings.properties index c71ddcda..401b7902 100644 --- a/src/main/resources/Strings.properties +++ b/src/main/resources/Strings.properties @@ -57,6 +57,7 @@ IDS_NOTIFY_SFZ_PARTIALLY_UNSUPPORTED_TRIGGER=Partially unsupported trigger value IDS_NOTIFY_SFZ_UNSUPPORTED_TRIGGER=Unsupported trigger value: %1\n IDS_NOTIFY_UNSUPPORTED_OPCODES=Unused SFZ opcodes: %1\n IDS_NOTIFY_UNSUPPORTED_GENERATORS=Unused SF2 generators: %1\n +IDS_NOTIFY_SF2_SKIP_EMPTY_PRESET=Skipping SoundFont preset '%1' because it contains no samples.\n IDS_NOTIFY_UNSUPPORTED_ATTRIBUTES=Unused <%1> attributes: %2\n IDS_NOTIFY_UNSUPPORTED_ELEMENTS=Unused <%1> child elements: %2\n IDS_NOTIFY_ERR_NO_SAMPLE_LENGTH=Could not retrieve length of sample.\n