import TOE template = '''<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE MIDINameDocument PUBLIC "-//MIDI Manufacturers Association//DTD MIDINameDocument 1.0//EN" "http://www.midi.org/dtds/MIDINameDocument10.dtd"> <MIDINameDocument> <Author>TOE Morpheus.py</Author> <MasterDeviceNames> <Manufacturer>E-mu</Manufacturer> <Model>Morpheus</Model> <CustomDeviceMode Name="Mode 1"> <ChannelNameSetAssignments> <ChannelNameSetAssign Channel="1" NameSet="Name Set 1"/> <ChannelNameSetAssign Channel="2" NameSet="Name Set 1"/> <ChannelNameSetAssign Channel="3" NameSet="Name Set 1"/> <ChannelNameSetAssign Channel="4" NameSet="Name Set 1"/> <ChannelNameSetAssign Channel="5" NameSet="Name Set 1"/> <ChannelNameSetAssign Channel="6" NameSet="Name Set 1"/> <ChannelNameSetAssign Channel="7" NameSet="Name Set 1"/> <ChannelNameSetAssign Channel="8" NameSet="Name Set 1"/> <ChannelNameSetAssign Channel="9" NameSet="Name Set 1"/> <ChannelNameSetAssign Channel="10" NameSet="Name Set 1"/> <ChannelNameSetAssign Channel="11" NameSet="Name Set 1"/> <ChannelNameSetAssign Channel="12" NameSet="Name Set 1"/> <ChannelNameSetAssign Channel="13" NameSet="Name Set 1"/> <ChannelNameSetAssign Channel="14" NameSet="Name Set 1"/> <ChannelNameSetAssign Channel="15" NameSet="Name Set 1"/> <ChannelNameSetAssign Channel="16" NameSet="Name Set 1"/> </ChannelNameSetAssignments> </CustomDeviceMode> <ChannelNameSet Name="Name Set 1"> <AvailableForChannels> <AvailableChannel Channel="1" Available="true"/> <AvailableChannel Channel="2" Available="true"/> <AvailableChannel Channel="3" Available="true"/> <AvailableChannel Channel="4" Available="true"/> <AvailableChannel Channel="5" Available="true"/> <AvailableChannel Channel="6" Available="true"/> <AvailableChannel Channel="7" Available="true"/> <AvailableChannel Channel="8" Available="true"/> <AvailableChannel Channel="9" Available="true"/> <AvailableChannel Channel="10" Available="true"/> <AvailableChannel Channel="11" Available="true"/> <AvailableChannel Channel="12" Available="true"/> <AvailableChannel Channel="13" Available="true"/> <AvailableChannel Channel="14" Available="true"/> <AvailableChannel Channel="15" Available="true"/> <AvailableChannel Channel="16" Available="true"/> </AvailableForChannels> <PatchBank Name="RAM Presets" ROM="false"> <MIDICommands> <ControlChange Control="0" Value="0"/> <ControlChange Control="32" Value="0"/> </MIDICommands> <UsesPatchNameList Name="RAM Presets"/> </PatchBank> <PatchBank Name="ROM Presets" ROM="true"> <MIDICommands> <ControlChange Control="0" Value="0"/> <ControlChange Control="32" Value="1"/> </MIDICommands> <UsesPatchNameList Name="ROM Presets"/> </PatchBank> <PatchBank Name="HyperPresets" ROM="false"> <MIDICommands> <ControlChange Control="0" Value="0"/> <ControlChange Control="32" Value="2"/> </MIDICommands> <UsesPatchNameList Name="HyperPresets"/> </PatchBank> </ChannelNameSet> %s </MasterDeviceNames> </MIDINameDocument> ''' # Send Sysex data requestSysex to device and receive and return # lengthExpected bytes of bulk dump data. def GetSysexBulkDump(device, requestSysex, lengthExpected): device.Send(requestSysex) while (device.NumOfBytesReceived() < lengthExpected): pass return device.Receive() # From the bulk dump data sysexData, extract and return a list of # patch names. Each name is of length nameLen. The first name starts # at byte offest startOffset. The next names starts at 'startOffset + # interval', 'startOffset + 2 * interval' and so on. def ExtractNameList(sysexData, numNames, startOffset, interval, nameLen): nameList = [] for i in range(numNames): nameList.append(sysexData[startOffset + i * interval : startOffset + i * interval + nameLen]) return nameList # Convert a list of patch names into the <PatchNameList> XML element # to be inserted into the MIDI name document representation. def PatchNameList(nameListName, nameList): patchNameList = ' <PatchNameList Name="%s">\n' % nameListName i = 0 for name in nameList: patchNameList += ' <Patch Number="P-%u" Name="%s" ProgramChange="%u" />\n' % (i, name, i) i += 1 patchNameList += ' </PatchNameList>\n' return patchNameList TOE.Initialize() d = TOE.Sysex('Morpheus') ramRomSysex = GetSysexBulkDump(d, '\xf0\x18\x0c\x00\x12\xf7', 3336) ramPresets = ExtractNameList(ramRomSysex, 128, 7, 13, 12) romPresets = ExtractNameList(ramRomSysex, 128, 7 + 13 * 128, 13, 12) hyperSysex = GetSysexBulkDump(d, '\xf0\x18\x0c\x00\x50\xf7', 1672) hyperPresets = ExtractNameList(hyperSysex, 128, 7, 13, 12) print template % (PatchNameList("RAM Presets", ramPresets) + \ PatchNameList("ROM Presets", romPresets) + \ PatchNameList("HyperPresets", hyperPresets)) TOE.Terminate()