Normally, users are allowed to select their own sound fonts. This is good for when a WAD has general (or no) custom music that's MIDI-based, but not intended to be only played with a specific soundfont.
However, this also presents some extra steps the end-user has to do if they play a level set where there are specific MIDIs that demand a specific soundfont, and won't sound right any other way. It also presents some annoying problems if the user has to (for some reason) switch soundfonts mid-experience - play a level that needs it that's partway through a level set, and you have to set it once the level comes up, then un-set it once you're done with the level that uses it. And god forbid if you have to do this multiple times in your playthrough...
What I propose, then, is a system where a level creator/packager can set it so that included SF2s gets used automatically by ZDoom with the presence of some info files included in the WAD/PK3/PK7. This way the packager can set all of this up for the end-user so they don't have to mess around with soundfonts, or accidentally forget to undo a soundfont change if they play a mod where using a soundfont is necessary for the music, but then play something else which will sound amusingly wrong with the "wrong" soundfont. ZDoom can then handle the swapping of soundfonts as needed, and the user can simply plug and play.
In terms of detection, this would work as follows:
- ZDoom reads the user's default soundfont/etc. settings, which sets a baseline universal setting (including if no embedded soundfonts wind up getting used). This is what the engine does already (I presume, anyway).
- ZDoom then scans the WAD/PK3/PK7 for a specific file that would contain auto-setting soundfont information (tentatively called SF2INFO).
- If not found, proceed as normal - user's sound settings, including soundfont, are used.
- If found, the engine checks and sets proper information for what soundfonts are loaded for whatever maps are selected in the SF2INFO, overriding the user's default soundfont settings for the level(s) as directed by the SF2INFO.
- This way, the MIDI-based tracks that use that soundfont, use their proper soundfont, without the end-user having to futz around with soundfonts, because it will only change them as directed by the SF2INFO - any map that is not defined by it, does not get adjusted by it, and we automatically fall back to the user's settings as the baseline.
- Engine execution then proceeds as usual.
Code: Select all
<Map Identifier>
<Soundfont to be used>
<Second Map Identifier>
<Soundfont to be used>
<...>
Let's say we want two specific levels, and ONLY two specific levels, to use an embedded soundfont, but nothing else. That'd look like this:
Code: Select all
MAP01
MySoundfont.sf2
MAP14
MySecondSoundfont.sf2
Ranges should be possible, as well:
Code: Select all
MAP01-16
KickAssSoundfont.sf2
MAP17-32
EvilSoundfont.sf2
What about if you want to use the same soundfonts for multiple sections? That works too:
Code: Select all
MAP01-08, MAP17-24
DimensionXSoundfont.sf2
MAP09-16
DimensionYSoundfont.sf2
MAP25-32
DimensionZSoundfont.sf2
Code: Select all
MAP*
UniversalSoundfont.sf2
Code: Select all
Z1M*
Episode1Soundfont.sf2
Z2M*
Episode2Soundfont.sf2
Code: Select all
E*M*
UniversalDoomSoundfont.sf2
Code: Select all
*
ThisCoversAllMapsHopefully.sf2
This would break down via search paths as thus:
- WAD: It'd be looking for lumps named whatever you've embedded them as in the WAD. You're way more limited on filename here due to the limitations of the WAD format to 8 characters with no extension. Indeed, being lumps, they won't have an extension either - so it's possible that we could say that any SF2INFO that doesn't have a .sf2 at the end of its Soundfont definition(s) is assumed to be a lump inside the WAD itself.
- PK3/PK7: Gain a new top-level namespace, soundfonts/, where your SF2s are expected to be located. Obviously it will be expecting a SF2INFO lump inside the root directory if you go this route.
- If missing but defined by SF2INFO: Naturally, we either throw an error if it's missing, or use the user-defined soundfont, but warn that the soundfont is missing and that your ears are possibly about to get raped.
- The presence of a SF2INFO means that ZDoom is expecting creator-defined soundfonts; if SF2INFO is missing, this is how we tell apart that the user is simply playing a level set that had no specific soundfonts intended in mind, and so no need to warn the user there.
- Conflicting Entries: ZDoom would need to detect if the user accidentally sets the same map (or maps) to use two different soundfonts (since it'd have no idea which soundfont to use otherwise). For example, if the user sets MAP07 to have its own soundfont, but there's also a second MAP07 definition, or a broad-scope definition such as MAP01-08 or MAP* that also is creating a second definition for that.
- A possibly "lazy way around it" if there's not two specific map definitions would be to either have it so that a map-specific definition overrules a broad-scope one (in other words, it would use the hand-defined MAP07 one and ignore the broad MAP01-08 or MAP* one for that map), or to have it be heirarchy-based - the first definition is considered the "base" and any definitions written after that are considered to overwrite that, just like how PWADs overwrite IWADs/earlier PWADs when used.
- Hard-defining two specific level entries would probably deserve either a warning (at a minimum) or possibly an abort.
- This does nothing for DLS or PATs, which only the TiMidity++ backend can use - FluidSynth is out of luck. However, creation/conversion of soundfonts is beyond the scope of what this is intended to address.
- Finally, if there's more than one SF2INFO, there is probably no manual way to reserve the conflict. But seeing as that means the end-user is trying to load two level packs at the same time and there is a high likelihood of conflict between the map data themselves, it probably should just get handled by the standard overriding rules - the file loaded last gets precedence. Having two actual SF2INFOs in one WAD/PK3/PK7 should be impossible, after all. And if for some reason they don't conflict but the SF2INFOs do, all that'd really be needed to fix it is writing up a merged SF2INFO that would get loaded after all the levels - but again, the odds of that are pretty small in my book (not to mention not ZDoom's problem, either).
If you've got any other questions, by all means, I'll try to answer them.