Add command line option to specify genmidi lump, identify instrument

when a voice is programmed.

Subversion-branch: /research
Subversion-revision: 1698
This commit is contained in:
Simon Howard 2009-09-30 17:59:35 +00:00
parent 457c7591d7
commit 2b81dd217f
1 changed files with 124 additions and 1 deletions

View File

@ -185,10 +185,30 @@ class InitChannel < OperatorEvent
operator_values(operator_2)
end
# Description of the instrument being loaded:
def instr_desc
instr_data = $instruments[values]
if instr_data == nil
return "- Unknown instrument"
end
result = ""
for possible in instr_data
result += "- Instrument ##{possible[:instrument]} " \
+ "(#{possible[:name]}) " \
+ "v#{possible[:voice]}\n"
end
result
end
def to_s
stringified = values.map { |val| sprintf("%02x", val) }
stringified = stringified.join(",")
"Initialising channel #{channel}: #{stringified}"
"Initializing channel #{channel}: #{stringified}\n" + instr_desc
end
end
@ -251,6 +271,107 @@ class BasicRegisterWrite < Event
end
end
# GENMIDI parsing code:
NUM_INSTRUMENTS = 175
def read_instrument(file)
result = []
36.times do
c = file.getc
result.push(c)
end
result
end
# "Flatten" voice data in the way that the Doom code will:
def flatten_voice(voice_data)
modulating = (voice_data[6] & 0x01) == 0;
# Voices 1 and 2 (for OPL3)
voice_data[6] |= 0x30;
# 2nd op always has level set to max
voice_data[12] |= 0x3f;
# 1st op has level set to max if not modulating
if !modulating
voice_data[5] |= 0x3f;
end
end
# Add a voice to the instruments lookup table.
def add_voice(instruments, voice_data, instr_num, voice_num, name)
if instruments[voice_data] == nil
instruments[voice_data] = []
end
instruments[voice_data].push({
:instrument => instr_num,
:voice => voice_num,
:name => name
})
end
def read_genmidi(filename)
instr_data = []
instr_names = []
File.open(filename) do |file|
header = file.read(8)
if header != "#OPL_II#"
raise "Header not found!"
end
NUM_INSTRUMENTS.times do
data = read_instrument(file)
instr_data.push(data)
end
NUM_INSTRUMENTS.times do
name = file.read(32).strip
instr_names.push(name)
end
end
instruments = {}
for i in 0...NUM_INSTRUMENTS
dual_voice = (instr_data[i][0] & 0x04) != 0
voice1 = instr_data[i][4, 13]
voice2 = instr_data[i][20, 13]
flatten_voice(voice1)
flatten_voice(voice2)
add_voice(instruments, voice1, i, 1, instr_names[i])
if dual_voice
add_voice(instruments, voice2, i, 2, instr_names[i])
end
end
instruments
end
def parse_cmdline
i = 0
$instruments = {}
while i < ARGV.length
if ARGV[i] == "-genmidi"
$instruments = read_genmidi(ARGV[i + 1])
i += 1
end
i += 1
end
end
def parse_file(stream)
register = nil
@ -335,6 +456,8 @@ MATCH_PATTERNS = [
MatchPattern.new(BasicRegisterWrite, [[0, 0]])
]
parse_cmdline
writes = parse_file($stdin)
offset = 0