MIDI Instrument Map and Rosegarden
Posted: Mon Feb 25, 2008 12:03 am
There's a chance that this is completely useless to anyone else than me. But here it is anyway.
I'm currently using Rosegarden as my MIDI sequencer and an extensive MIDI instrument map to load instruments without using any of the GUIs. To make it happen I first created the instrument map using Fantasia, having already put together an instrument database made it a breeze to sort through and adding the wanted instruments to the map.
If you build large maps you will soon realize that there seems to be some complexity issues relating to the communication between Fantasia and LinuxSampler when adding an instrument take longer and longer time (it seems like Fantasia update after each adding by receiving and rebuilding the whole map). [Update: This is no longer true and have been fixed in both Fantasia and LinuxSampler.] So I prefer to build it in chunks, separating the banks into separate maps and then merge them by hand in a text editor after exporting them. And if you realize you need to reorder banks and programs then doing it manually is currently the only option.
After creating the map with LinuxSampler and tidying it up a bit in a text editor I use the following pyton script, lscp2rgd.py, to create a corresponding RGD file (a Rosegarden Device file) that can be imported into Rosegarden:
The script takes an LSCP file that looks something like the following excerpt of the piano bank. (I only use comments to name the banks.)
And gets turned into something like this:
I added some statistics to the script and it counted 800 programs in 35 banks in my case.
I'm currently using Rosegarden as my MIDI sequencer and an extensive MIDI instrument map to load instruments without using any of the GUIs. To make it happen I first created the instrument map using Fantasia, having already put together an instrument database made it a breeze to sort through and adding the wanted instruments to the map.
If you build large maps you will soon realize that there seems to be some complexity issues relating to the communication between Fantasia and LinuxSampler when adding an instrument take longer and longer time (it seems like Fantasia update after each adding by receiving and rebuilding the whole map). [Update: This is no longer true and have been fixed in both Fantasia and LinuxSampler.] So I prefer to build it in chunks, separating the banks into separate maps and then merge them by hand in a text editor after exporting them. And if you realize you need to reorder banks and programs then doing it manually is currently the only option.
After creating the map with LinuxSampler and tidying it up a bit in a text editor I use the following pyton script, lscp2rgd.py, to create a corresponding RGD file (a Rosegarden Device file) that can be imported into Rosegarden:
Code: Select all
#!/usr/bin/python
import sys, gzip, re
pattern = re.compile(r"MAP[\s]*MIDI_INSTRUMENT[\s]*([\d]+)[\s]*([\d]+)[\s]*([\d]+)[\s]*([\w]+)[\s]*'([\S]+)'[\s]*([\d]+)[\s]*([\d]+.[\d]+)[\s]*([\w]+)[\s]*'(.+)'[\s]*$")
preamble = '''<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rosegarden-data>
<rosegarden-data>
<studio thrufilter="0" recordfilter="0">
<device id="0" name="LinuxSampler" type="midi">
<librarian name="Anders Dahnielson" email="anders@dahnielson.com"/>
'''
postamble = '''
</device>
</studio>
</rosegarden-data>
'''
rgd = open('%s.rgd' % (sys.argv[1]), 'w')
out = gzip.GzipFile(mode='w', filename = "audio/x-rosegarden-device", fileobj=rgd)
out.filename = "audio/x-rosegarden-device"
out.write(preamble)
total_programs = 0
current_bank = -1
lscp = open(sys.argv[1], 'r')
for line in lscp:
line = line.strip()
tokens = line.split(' ')
if tokens[0] == '#' and tokens[1] and len(tokens) == 2:
bank_name = tokens[1]
elif tokens[0] == 'MAP' and tokens[1] == 'MIDI_INSTRUMENT':
total_programs += 1
m = pattern.match(line)
bank, program, name = int(m.group(2)), int(m.group(3)), m.group(9).replace(r"\'", "'")
if bank != current_bank:
if current_bank != -1:
out.write(' </bank>\n\n')
current_bank = int(bank)
out.write(' <bank name="%s" msb="%d" lsb="%d">\n' % (bank_name, 0, bank))
out.write(' <program id="%d" name="%s"/>\n' % (program, name))
out.write(' </bank>\n')
out.write(postamble)
lscp.close()
out.close()
rgd.close()
print "%d programs in %d banks" % (total_programs, current_bank+1)
Code: Select all
# PI
MAP MIDI_INSTRUMENT 0 27 0 GIG '/home/anders/Studio/instruments/gig/Mats\x20Helgesson/maestro_concert_grand_v2.gig' 0 1.0 ON_DEMAND 'Maestro Concert Grand'
MAP MIDI_INSTRUMENT 0 27 1 GIG '/home/anders/Studio/instruments/gig/Mats\x20Helgesson/maestro_concert_grand_v2.gig' 1 1.0 ON_DEMAND 'MCG Sustains + Releases'
MAP MIDI_INSTRUMENT 0 27 2 GIG '/home/anders/Studio/instruments/gig/G-Town/G-Town_Church_Piano_Staccs.gig' 0 1.0 ON_DEMAND 'Piano Staccs'
MAP MIDI_INSTRUMENT 0 27 3 GIG '/home/anders/Studio/instruments/gig/G-Town/G-Town_Church_Piano_FX.gig' 0 1.0 ON_DEMAND 'Prepared Piano Effects'
MAP MIDI_INSTRUMENT 0 27 4 GIG '/home/anders/Studio/instruments/gig/Westgate/Demo/Westgate\x20Piano\x20FX.gig' 0 1.0 ON_DEMAND 'Piano FX'
MAP MIDI_INSTRUMENT 0 27 5 GIG '/home/anders/Studio/instruments/gig/SAM/Demo/SAM\x20Ambient\x20Bass\x20Piano\x20+\x20Tbn.gig' 0 1.0 ON_DEMAND 'SAM Amb Bass Piano'
MAP MIDI_INSTRUMENT 0 27 6 GIG '/home/anders/Studio/instruments/gig/SAM/Demo/SAM\x20Ambient\x20Bass\x20Piano\x20+\x20Tbn.gig' 1 1.0 ON_DEMAND 'SAM Amb Bass Piano (-8)'
MAP MIDI_INSTRUMENT 0 27 7 GIG '/home/anders/Studio/instruments/gig/SAM/Demo/SAM\x20Ambient\x20Bass\x20Piano\x20+\x20Tbn.gig' 2 1.0 ON_DEMAND 'SAM Amb Bass Piano + Tbn'
MAP MIDI_INSTRUMENT 0 27 8 GIG '/home/anders/Studio/instruments/gig/SAM/Demo/SAM\x20Ambient\x20Bass\x20Piano\x20+\x20Tbn.gig' 3 1.0 ON_DEMAND 'SAM Amb Bass Piano + Tbn (-8)'
Code: Select all
<bank name="PI" msb="0" lsb="27">
<program id="0" name="Maestro Concert Grand"/>
<program id="1" name="MCG Sustains + Releases"/>
<program id="2" name="Piano Staccs"/>
<program id="3" name="Prepared Piano Effects"/>
<program id="4" name="Piano FX"/>
<program id="5" name="SAM Amb Bass Piano"/>
<program id="6" name="SAM Amb Bass Piano (-8)"/>
<program id="7" name="SAM Amb Bass Piano + Tbn"/>
<program id="8" name="SAM Amb Bass Piano + Tbn (-8)"/>
</bank>