Embeddable Soundfonts in WADs/PK3s/PK7s

Remember, just because you request it, that doesn't mean you'll get it.

Moderator: GZDoom Developers

User avatar
Dark Pulse
Posts: 66
Joined: Fri Nov 21, 2014 5:35 pm
Operating System Version (Optional): Windows 10
Graphics Processor: nVidia with Vulkan support

Embeddable Soundfonts in WADs/PK3s/PK7s

Post by Dark Pulse »

I've been kicking around soundfont-related stuff in my head over the last few days.

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:
  1. 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).
  2. 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.
  3. 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.
  4. Engine execution then proceeds as usual.
A SF2INFO lump is based loosely upon the MUSINFO lump, and would look something like this:

Code: Select all

<Map Identifier>
<Soundfont to be used>

<Second Map Identifier>
<Soundfont to be used>

<...>
Some examples.

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
This would set MAP01 to use a specific soundfont, and MAP14 to use a second soundfont entirely. However, from MAP02 on to MAP13, and from MAP15 onward, no specific soundfont would get used, and we would revert to the user's general soundfont settings.

Ranges should be possible, as well:

Code: Select all

MAP01-16
KickAssSoundfont.sf2

MAP17-32
EvilSoundfont.sf2
This would set all maps from MAP01-MAP16 to use one soundfont, and 17-32 to use a second. The user's normal soundfont options don't get used in this level set at all (assuming there's only 32 maps like most total replacements, anyway - in this example, a theoretical MAP33 would actually use the user's default soundfont settings, since it's not defined.)

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
If you need just one Soundfont to apply to every single level, something like this could work without needing to set a whole range or individually-defined maps:

Code: Select all

MAP*
UniversalSoundfont.sf2
It should account for level sets that have non-standard map naming conventions as well:

Code: Select all

Z1M*
Episode1Soundfont.sf2

Z2M*
Episode2Soundfont.sf2
Universally naming stuff using Doom 1/Heretic map naming conventions also can be wildcarded just fine:

Code: Select all

E*M*
UniversalDoomSoundfont.sf2
The only thing wildcards can't really cover is if the mapper decides to name every map a unique name with no particular numerical order. In this case, you just kind of go for something like this, and hope for the best:

Code: Select all

*
ThisCoversAllMapsHopefully.sf2
...but if you do that, probably more than the engine will hate you. Your players, for starters.

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.
A few minor hangups:
  1. 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.
  2. 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.
  3. 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.
  4. 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).
Anyway, sorry for the long post, but I wanted to try to establish the rules they obey, more or less how they work, and so on. Hopefully you guys agree this would be good to pick up.

If you've got any other questions, by all means, I'll try to answer them.
User avatar
abbuw
Posts: 651
Joined: Tue Jun 12, 2012 10:24 am
Location: South Lake Hills

Re: Embeddable Soundfonts in WADs/PK3s/PK7s

Post by abbuw »

I don't want to poo poo all over your ideas, but if you're really concerned about your music sounding a certain way, wouldn't it be easier to turn your midis into modules or something? They're lighter than streamed audio, and probably lighter overall than having a whole soundfont.
User avatar
wildweasel
Posts: 21706
Joined: Tue Jul 15, 2003 7:33 pm
Preferred Pronouns: He/Him
Operating System Version (Optional): A lot of them
Graphics Processor: Not Listed
Contact:

Re: Embeddable Soundfonts in WADs/PK3s/PK7s

Post by wildweasel »

abbuw wrote:I don't want to poo poo all over your ideas, but if you're really concerned about your music sounding a certain way, wouldn't it be easier to turn your midis into modules or something? They're lighter than streamed audio, and probably lighter overall than having a whole soundfont.
I can see a good use case for, say, the Doom 64 soundtrack. It'd take far less space to have the sound font appear only once in the data, than to include the sample data with every single song. For 32+ songs, that'd add up fast.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49056
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: Embeddable Soundfonts in WADs/PK3s/PK7s

Post by Graf Zahl »

Embedding the sound font is not really feasible, though, because all code reading from it needs them as separate files. And the rest can already be done through the $mididevice option in SNDINFO - all that may be needed here is some flexibility where to look for the file.
User avatar
Dark Pulse
Posts: 66
Joined: Fri Nov 21, 2014 5:35 pm
Operating System Version (Optional): Windows 10
Graphics Processor: nVidia with Vulkan support

Re: Embeddable Soundfonts in WADs/PK3s/PK7s

Post by Dark Pulse »

wildweasel wrote:I can see a good use case for, say, the Doom 64 soundtrack. It'd take far less space to have the sound font appear only once in the data, than to include the sample data with every single song. For 32+ songs, that'd add up fast.
That's a good example, yes. Another would be Team GEC's Playstation Doom conversion, although that uses an older forked GZDoom and is more tailor-built for the purpose, but it too uses its own soundfont.
Graf Zahl wrote:Embedding the sound font is not really feasible, though, because all code reading from it needs them as separate files. And the rest can already be done through the $mididevice option in SNDINFO - all that may be needed here is some flexibility where to look for the file.
What I meant by "embedding" the soundfont is really just that it's included along with the WAD/PK3/PK7 - the soundfont would indeed be a separate file within those files, and the idea I'd proposed essentially amounts to having ZDoom automatically be aware of this soundfont and use it if a map pack is loaded that contains instructions on what soundfont to use (and which levels to use it on).

Not sure if there's confusion there, or if what you're saying is more along the lines of "the code reading from it expects soundfonts to be their own file entirely separate from anything else."

In which case, well, shit, because the whole idea behind this is to essentially allow an automated override so the end-user doesn't have to futz around with stuff with mods that use soundfonts and then get all mad when the music doesn't sound right (because they didn't set it up right), or get confused when they forget to un-set it after they've played some mod that uses it and wonder why the music sounds atrocious until they remember it's due to the soundfont.

I suppose that might still be technically possible to set up without the embedding part, but there'd still need to be a way for ZDoom to be aware of a creator-specified soundfont and be able to automatically map it accordingly. Embedding would just be a logical step if that much is going to be done for it though, IMO.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49056
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: Embeddable Soundfonts in WADs/PK3s/PK7s

Post by Graf Zahl »

Like I said, you can already set a soundfont for single MIDI files, in fact you can also set the MIDI synth to be used with the sound font. I don't like a blanket general override just because the file is present. This needs the more fine grained control the SNDINFO option offers. I think the only missing piece here is that it needs to be able to find a soundfont if it's in the same folder as the WAD containing the reference.
User avatar
Kinsie
Posts: 7399
Joined: Fri Oct 22, 2004 9:22 am
Graphics Processor: nVidia with Vulkan support
Location: MAP33
Contact:

Re: Embeddable Soundfonts in WADs/PK3s/PK7s

Post by Kinsie »

abbuw wrote:I don't want to poo poo all over your ideas, but if you're really concerned about your music sounding a certain way, wouldn't it be easier to turn your midis into modules or something? They're lighter than streamed audio, and probably lighter overall than having a whole soundfont.
I'd prefer modules myself, but with the Doom 64 soundtrack in particular I haven't had a whole lot of luck converting them into tracker modules using OpenMPT.
User avatar
Dark Pulse
Posts: 66
Joined: Fri Nov 21, 2014 5:35 pm
Operating System Version (Optional): Windows 10
Graphics Processor: nVidia with Vulkan support

Re: Embeddable Soundfonts in WADs/PK3s/PK7s

Post by Dark Pulse »

Graf Zahl wrote:Like I said, you can already set a soundfont for single MIDI files, in fact you can also set the MIDI synth to be used with the sound font. I don't like a blanket general override just because the file is present. This needs the more fine grained control the SNDINFO option offers. I think the only missing piece here is that it needs to be able to find a soundfont if it's in the same folder as the WAD containing the reference.
That's possible I suppose, but then it'd clutter up a user's PWAD folder if they've got one, and even then, that'd force decompression of the file from its original archive - I run a lot of zipped WADs straight from their zips, for example. I know hard drive space is usually not an issue nowadays, but zipping up a PK3/PK7 and Soundfont and then decompressing them in the same folder just so that you don't have an embedded soundfont in the PK3/PK7 is a bit of a waste of space, compared to if you could embed it and then just distribute the PK3/PK7/ZIP and be done with it.

I'm not sure if this is still up-to-date, but looking at SNDINFO on the Wiki, that would present a potential issue of its own. The stuff for $mididevice says that this only works on Windows only, and while the bulk of ZDoom players are on Windows, there are the Mac and Linux holdouts, not to mention potentially other ports (still holding out hope for an eventual port to the Switch :P). Basically, if that's still true, while $mididevice would work fine for Windows users, the Mac/Linux people would still have to manually config stuff.

That said, what we're arguing over at this point seems to be more implementation details as opposed to opposition to the idea, so something can be figured out with enough time probably.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49056
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: Embeddable Soundfonts in WADs/PK3s/PK7s

Post by Graf Zahl »

The information about $mididevice is old and outdated, it works on all systems. As for "forced to decompress", that'd be needed anyway, just instead of packing it into a folder you can see it'd have to place the extracted soundfont in its userdata folder which is hidden on most systems. I cannot change the problem that none of the softsynths can read a sound font from within an archive. You couldn't run a .pk3 from within an archive either.
Post Reply

Return to “Feature Suggestions [GZDoom]”