genmidi: Add GENMIDI dump script.

Helper script to dump the contents of a GENMIDI file into separate
SBI files and a configuration matching the format of config.py.
This commit is contained in:
Simon Howard 2012-01-04 01:36:49 +00:00
parent 3b96d7f1de
commit b0253e3176
2 changed files with 98 additions and 3 deletions

94
lumps/genmidi/dumpgenmidi Normal file
View file

@ -0,0 +1,94 @@
#!/usr/bin/env python
#
# Copyright (c) 2011, 2012
# Contributors to the Freedoom project. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the freedoom project nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# ----------------------------------------------------------------------
#
# Dump the contents of a GENMIDI lump into separate .sbi instrument files,
# and output a config to stdout.
#
import genmidi
import sbi_file
import sys
def print_instr_def(filename, filename2, instr):
result = "Instrument(\"%s\"" % filename
if instr.voice2 is not None:
result += (", \"%s\"" % filename2)
if instr.fixed_note is not None:
result += (", note=%i" % instr.fixed_note)
if instr.offset1 != 0:
result += (", off1=%i" % instr.offset1)
if instr.offset2 != 0:
result += (", off2=%i" % instr.offset2)
result += ")"
print "\t%s," % result
def dump_instrument(filename, filename2, instr):
sbi_file.write(filename, instr.voice1)
if instr.voice2 is not None:
sbi_file.write(filename2, instr.voice2)
if len(sys.argv) != 2:
print >> sys.stderr, "Usage: %s <filename>" % sys.argv[0]
sys.exit(-1)
instruments = genmidi.read(sys.argv[1])
main_instrs = instruments[0:128]
percussion = instruments[128:]
print "INSTRUMENTS = ["
for i in range(len(main_instrs)):
instr = main_instrs[i]
filename = "instruments/instr%03i.sbi" % (i+1)
filename2 = "instruments/instr%03i-2.sbi" % (i+1)
dump_instrument(filename, filename2, instr)
print_instr_def(filename, filename2, instr)
print "]"
print
print "PERCUSSION = ["
for i in range(len(percussion)):
instr = percussion[i]
filename = "instruments/perc%02i.sbi" % (i+35)
filename2 = "instruments/perc%02i-2.sbi" % (i+35)
dump_instrument(filename, filename2, instr)
print_instr_def(filename, filename2, instr)
print "]"

View file

@ -135,7 +135,7 @@ def write(filename, instruments):
f.close() f.close()
def decode_voice(data): def decode_voice(data, name):
fields = struct.unpack("<BBBBBBBBBBBBBBh", data) fields = struct.unpack("<BBBBBBBBBBBBBBh", data)
@ -145,19 +145,20 @@ def decode_voice(data):
result["m_ksl_volume"] = result["m_ksl"] | result["m_volume"] result["m_ksl_volume"] = result["m_ksl"] | result["m_volume"]
result["c_ksl_volume"] = result["c_ksl"] | result["c_volume"] result["c_ksl_volume"] = result["c_ksl"] | result["c_volume"]
result["name"] = name.rstrip("\0")
return result return result
def decode_instrument(data, name): def decode_instrument(data, name):
flags, finetune, fixed_note = struct.unpack("<hBB", data[0:4]) flags, finetune, fixed_note = struct.unpack("<hBB", data[0:4])
voice1 = decode_voice(data[4:20]) voice1 = decode_voice(data[4:20], name)
offset1 = voice1["note_offset"] offset1 = voice1["note_offset"]
# Second voice? # Second voice?
if (flags & FLAG_TWO_VOICE) != 0: if (flags & FLAG_TWO_VOICE) != 0:
voice2 = decode_voice(data[20:]) voice2 = decode_voice(data[20:], name)
offset2 = voice2["note_offset"] offset2 = voice2["note_offset"]
else: else:
voice2 = None voice2 = None