From 75cedb719385b70d08805483fbeda07222031f98 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 31 Jan 2014 05:38:44 +0000 Subject: [PATCH] dmxgus: Add comparison MID generator script. This script generates a MIDI file that plays all of the comparison groups from config.py. This allows instruments to be compared, so that similar-sounding instruments can be grouped together. --- lumps/dmxgus/comparison.py | 99 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 lumps/dmxgus/comparison.py diff --git a/lumps/dmxgus/comparison.py b/lumps/dmxgus/comparison.py new file mode 100644 index 00000000..2c0756db --- /dev/null +++ b/lumps/dmxgus/comparison.py @@ -0,0 +1,99 @@ +# 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) +