freedoom/lumps/dmxgus/comparison.py
Mike Swanson 8835afef5f Copyright date bump and apply SPDX tags.
The tags are shorthand for the license of each file and avoid
copying the full license text into each one (and avoids having
to manually update the dates in each one...).
2017-02-15 16:41:53 -08:00

101 lines
3.1 KiB
Python

# SPDX-License-Identifier: BSD-3-Clause
#
# Generate comparison MIDI file.
#
# The comparison MIDI is used for testing and tweaking the similarity
# groups in the configuration file. In each group, the instruments in
# the group should sound broadly similar, and the first in the group
# should be able to substitute for any member of the group.
#
# Each similarity group is played in order, with a pause between each
# instrument. A programme of the instruments is printed to stdout so
# that the user can identify each instrument in order.
#
# To use the comparison MIDI, use a port that supports Timidity for
# MIDI playback, and configure it to use the GUS patch set (use
# music/dgguspat.zip from the idgames archive). Use the "full"
# configuration file (timidity.cfg in the .zip) so that every
# instrument is used for playback. Rename comparison.mid to
# d_runnin.lmp and run with '-file d_runnin.lmp -warp 1', so that the
# music plays.
from config import *
import midi
def instrument_num(instrument):
"""Given a GUS patch name, get the MIDI instrument number.
For percussion instruments, the instrument number is offset
by 128.
"""
for key, name in GUS_INSTR_PATCHES.items():
if name == instrument:
return key
raise Exception('Unknown instrument %s' % instrument)
pattern = midi.Pattern(resolution=48)
track = midi.Track()
track.append(midi.ControlChangeEvent(tick=0, channel=9, data=[7, 92]))
time = 500
for group in SIMILAR_GROUPS:
# Don't bother with special effects.
#if group[0] == 'blank':
# continue
print "Group: "
empty = True
for instrument in group:
inum = instrument_num(instrument)
# For normal instruments, play a couple of different notes.
# For percussion instruments, play a couple of note on
# the percussion channel.
if inum <= 128:
print "\t%s (%i)" % (instrument, inum)
track.extend([
midi.ProgramChangeEvent(tick=time, channel=0,
data=[inum]),
midi.NoteOnEvent(tick=0, channel=0,
velocity=92, pitch=midi.A_3),
midi.NoteOffEvent(tick=50, channel=0,
velocity=92, pitch=midi.A_3),
midi.NoteOnEvent(tick=0, channel=0,
velocity=92, pitch=midi.B_3),
midi.NoteOffEvent(tick=50, channel=0,
velocity=92, pitch=midi.B_3),
])
else:
print "\t%s (percussion %i)" % (instrument, inum-128)
track.extend([
midi.NoteOnEvent(tick=time, channel=9,
velocity=92, pitch=inum-128),
midi.NoteOffEvent(tick=50, channel=9,
pitch=inum-128),
midi.NoteOnEvent(tick=0, channel=9,
velocity=92, pitch=inum-128),
midi.NoteOffEvent(tick=50, channel=9,
pitch=inum-128),
])
empty = False
time = 100
if not empty:
time = 500
# Four drumbeats indicate the end of the track and that the music is
# going to loop.
for i in range(4):
track.extend([
midi.NoteOnEvent(tick=20, channel=9, velocity=92, pitch=35),
midi.NoteOffEvent(tick=20, channel=9, pitch=35),
])
track.append(midi.EndOfTrackEvent(tick=1))
pattern.append(track)
# Save the pattern to disk
midi.write_midifile("comparison.mid", pattern)