mirror of
https://github.com/freedoom/freedoom.git
synced 2025-09-01 13:25:46 -04:00
dmxgus: Change instrument order to work around DMX.
The DMX sound library used by Vanilla Doom has a bug where instruments referencing other instruments as stand-ins can only reference instruments listed earlier in the file. Actually, the instrument references are just arbitrary cross-reference tags and the first instrument to use that tag is used for all instruments with that tag. This behavior can have some strange effects; more information can be found on David Flater's page: <http://www.flaterco.com/kb/DOOM/DMXGUS/> This has consequences for Freedoom's GENMIDI generation, particularly as Chocolate Doom now emulates this behavior. To avoid assigning the wrong instrument mappings, change the ordering of instruments in the output file, so that "leader" instruments always appear earlier in the file than instruments that reference them.
This commit is contained in:
parent
f069cc2ee3
commit
6198796e95
1 changed files with 43 additions and 4 deletions
|
@ -43,6 +43,14 @@ import sys
|
|||
import config
|
||||
import stats
|
||||
|
||||
HEADER_TEXT = """
|
||||
# Freedoom GUS config.
|
||||
# Autogenerated by the gen-ultramid script.
|
||||
# Please do not manually edit this file!
|
||||
# The ordering of entries in this file is significant, to work around a
|
||||
# bug in Doom's DMX sound library.
|
||||
"""
|
||||
|
||||
def normalize_stats(stats):
|
||||
"""Normalize the gathered instrument statistics.
|
||||
|
||||
|
@ -154,6 +162,39 @@ def mapping_for_size(size):
|
|||
|
||||
return result
|
||||
|
||||
def instrument_patches(mappings):
|
||||
"""Returns list of MIDI instruments in an appropriate order for output.
|
||||
|
||||
The ordering in the output file is important, because of a bug in the
|
||||
DMX sound library; when patches are shared between instruments it is
|
||||
only possible to refer to instruments listed earlier in the file.
|
||||
|
||||
Args:
|
||||
mappings: List of mappings from instrument ID to leader instrument.
|
||||
Yields:
|
||||
A tuple containing each MIDI instrument number and patch file name
|
||||
to load.
|
||||
"""
|
||||
done_instr_ids = set()
|
||||
# Make multiple passes until we've done all the instruments.
|
||||
while len(done_instr_ids) < len(config.GUS_INSTR_PATCHES):
|
||||
made_progress = False
|
||||
for instr_id, name in sorted(config.GUS_INSTR_PATCHES.items()):
|
||||
for mapping in mappings:
|
||||
mapped_instr_id = mapping[instr_id]
|
||||
if (instr_id != mapped_instr_id and
|
||||
mapped_instr_id not in done_instr_ids):
|
||||
break
|
||||
else:
|
||||
if instr_id not in done_instr_ids:
|
||||
yield instr_id, name
|
||||
done_instr_ids.add(instr_id)
|
||||
made_progress = True
|
||||
|
||||
assert made_progress, (
|
||||
"infinite loop while producing patches list")
|
||||
|
||||
|
||||
if len(sys.argv) != 2:
|
||||
print("Usage: %s <filename>" % sys.argv[0])
|
||||
sys.exit(1)
|
||||
|
@ -166,11 +207,9 @@ mappings = (
|
|||
)
|
||||
|
||||
with open(sys.argv[1], "w") as output:
|
||||
output.write("# Freedoom GUS config.\n"
|
||||
"# Autogenerated by the gen-ultramid script.\n"
|
||||
"# Please do not manually edit this file!\n")
|
||||
output.write(HEADER_TEXT.lstrip())
|
||||
|
||||
for instr_id, name in sorted(config.GUS_INSTR_PATCHES.items()):
|
||||
for instr_id, name in instrument_patches(mappings):
|
||||
line = "%i, %i, %i, %i, %i, %s" % (
|
||||
instr_id,
|
||||
mappings[0][instr_id],
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue