#!/usr/bin/python #============================================================================= # MusE # Linux Music Editor # $Id:$ # # Copyright (C) 1999-2011 by Werner Schweer and others # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the # Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #============================================================================= import sys import os import string version = "0.6" ########################################## ########################################## # # MusE song format converter # ######################################### ######################################### # blocks to remove: blocks = [ ["",""], ["",""], ["", ""], ["", ""], ["", ""], ["", ""], ["", ""], ["_font", "/>"], ["",""], ["",""], ["",""], ["",""], ["",""], ["",""], ["",""], ["",""], ["",""], ["",""], ["",""], [""], ["",""], ["",""], ["",""], ["",""], ["",""], ["",""], [""], [""], [""], ["",""], [""], ["",""], ["","","","","","","","", "","","",""] adata=[] synths=[] clips=[] midiports=[] class MusEConvert: def __init__(self): self.insidePart = False self.insideWaveTrack=False self.currWaveTrackName="" # parse string and look for blocks to remove def findAndSkipBlock(self, theFile, currLine): for line in blocks: if string.find(currLine , line[0]) > -1: #print "Skipping %s"%line[0] self.loopUntil(theFile, currLine, line[1]) return True return False # when a block has been found, loop until the end-tag. def loopUntil(self, theFile, currLine, tagToFind): loopEnd = False if string.find(currLine , tagToFind) > -1: loopEnd = True while loopEnd == False: line = inFile.readline() if string.find(line, tagToFind) > -1: loopEnd = True def fixComma(self, theFile, currLine): newStr = string.replace(currLine , ",",".") return newStr def getSynth(self, theFile, currLine): line = theFile.readline() # clas = self.getSimpleValue(line) line = theFile.readline() # name = self.getSimpleValue(line) line = theFile.readline() # port = self.getSimpleValue(line) line = theFile.readline() # guiVisible = self.getSimpleValue(line) stateInfo = [] line = theFile.readline() notFoundStateEnd= True if string.find(line , " -1: notFoundStateEnd = True line = theFile.readline() while notFoundStateEnd: if string.find(line , " -1: event = [] event.append(line) notFoundEventEnd = True if string.find(line , "/>") > -1: notFoundEventEnd = False line = theFile.readline() while notFoundEventEnd: if string.find(line , " -1: notFoundEventEnd = False event.append(line) line = theFile.readline() stateInfo.append(event) if string.find(line , " -1: notFoundStateEnd = False # got all events theFile.readline() # ch = self.getSimpleValue(line) conn = "" if atype == "audiomaster": # don't read any lines pass else: line = theFile.readline() # conn = self.getSimpleValue(line) line = theFile.readline() # vol = self.getSimpleValue(line) line = theFile.readline() # pan = self.getSimpleValue(line) line = theFile.readline() # mute = self.getSimpleValue(line) line = theFile.readline() # solo = self.getSimpleValue(line) line = theFile.readline() # pre = self.getSimpleValue(line) line = theFile.readline() # off = self.getSimpleValue(line) line = theFile.readline() # -1: notFoundPlugEnd = True while notFoundPlugEnd: p1.append(line) line = theFile.readline() # -1: p1.append(line) notFoundPlugEnd = False line = theFile.readline() # -1: notFoundPlugEnd = True while notFoundPlugEnd: p2.append(line) line = theFile.readline() # -1: p2.append(line) notFoundPlugEnd = False line = theFile.readline() # -1: notFoundPlugEnd = True while notFoundPlugEnd: p3.append(line) line = theFile.readline() # -1: p3.append(line) notFoundPlugEnd = False line = theFile.readline() # -1: notFoundPlugEnd = True while notFoundPlugEnd: p4.append(line) line = theFile.readline() # -1: p3.append(line) notFoundPlugEnd = False print "atype=", atype print "p1=", p1 print "p2=", p2 print "p3=", p3 print "p4=", p4 return([atype,name,idx,ch,conn,vol,pan,mute,solo,pre,off, p1,p2,p3,p4]) # add them together def checkAGroup(self, theFile, currLine): if string.find(currLine , " -1: print "AUDIOGROUP" theFile.readline() # idx = self.getProperty(currLine, "idx") print "idx=",idx data = self.getAudio(theFile,currLine,"audiogroup", "Group %s"%(chr(int(idx)+65)),idx) adata.append(data) theFile.readline() # return True else: return False def checkSynth(self, theFile, currLine): if string.find(currLine , " -1: print "SYNTH" synt = self.getSynth(theFile,currLine) data = self.getAudio(theFile,currLine,"synth", synt[1], 0) print "got synth, name=%s route=%s",synt[1], data[5] theFile.readline() # synths.append(synt) adata.append(data) return True else: return False def checkAMaster(self, theFile, currLine): if string.find(currLine , " -1: print "AUDIOMASTER" theFile.readline() # data = self.getAudio(theFile,currLine,"audiomaster", "Master",-1) adata.append(data) theFile.readline() # return True else: return False def checkAInput(self, theFile, currLine): if string.find(currLine , " -1: print "AUDIOINPUT" theFile.readline() # idx = self.getProperty(currLine, "idx") data = self.getAudio(theFile,currLine,"audioinput", "In 1",idx) adata.append(data) theFile.readline() # return True else: return False # returns the property def getProperty(self, currLine, tag): prePtr = string.find(currLine , tag) if prePtr == -1: return -1 firstPtr = string.find(currLine[prePtr:] , "\"") lastPtr = string.find(currLine[firstPtr+prePtr+1:] , "\"") return currLine[firstPtr+prePtr+1:firstPtr+prePtr+lastPtr+1] def checkMGroup(self, theFile, currLine): if string.find(currLine , " -1: print "MIDIPORT" idx = self.getProperty(currLine, "idx") line = theFile.readline() # inst = self.getSimpleValue(line) line = theFile.readline() # name = self.getSimpleValue(line) line = theFile.readline() # rec = self.getSimpleValue(line) midiports.append([idx, inst, name,rec]) # add them together line = theFile.readline() # return True else: return False # retrieve the value of a simple XML tag # format is important, must be: # value def getSimpleValue(self, line): firstPtr = string.find(line, ">") # find end of first tag lastPtr = string.find(line, "") > -1: if self.insidePart == False: print "CLIP" line = theFile.readline() # fil = self.getSimpleValue(line) line = theFile.readline() # nam = self.getSimpleValue(line) line = theFile.readline() # tick = self.getSimpleValue(line) clips.append([nam, fil, tick]) # add them together line = theFile.readline() # line = theFile.readline() # else: print "insertClip" clipname = self.getSimpleValue(currLine) for clip in clips: if clip[0] == clipname: outFile.write(" %s\n"%(clip[2])) outFile.write(" %s\n"%(clip[1])) return True else: return False def checkPart(self, theFile, currLine): if string.find(currLine , "") > -1: print "PART" self.insidePart = True elif string.find(currLine , "") > -1: print "/PART" self.insidePart = False def checkWaveTrack(self, theFile, currLine): if string.find(currLine , "") > -1: print "/WAVETRACK" self.insideWaveTrack = False return False elif string.find(currLine , "") > -1: print "WAVETRACK" self.insideWaveTrack = True return False if self.insideWaveTrack: # create dummy adata for the routing if string.find(currLine , "") > -1: con = self.getSimpleValue(currLine) #adata.append([atype,name,idx,ch,conn,vol,pan,mute,solo,pre,off, p1,p2,p3,p4]) print ["wavetrack", self.currWaveTrackName,0,0,con,0,0,0,0,0,0,0,0,0,0] adata.append(["wavetrack", self.currWaveTrackName,0,0,con,0,0,0,0,0,0,0,0,0,0]) return True elif string.find(currLine , " -1: print "AUDIONODE - in wave track" return True elif string.find(currLine , " -1: print "AUDIONODE - in wave track" return True elif string.find(currLine , "") > -1: vol = self.getSimpleValue(currLine) outFile.write(" \n"%vol) outFile.write(" \n") return True elif string.find(currLine , "") > -1: pan = self.getSimpleValue(currLine) outFile.write(" \n"%pan) outFile.write(" \n") return True return False def getWaveTrackName(self, theFile, currLine): if self.insideWaveTrack and not self.insidePart: if string.find(currLine , "") > -1: print "WAVETRACK - NAME" self.currWaveTrackName = self.getSimpleValue(currLine) print "self.currWaveTrackName =", self.currWaveTrackName elif self.insideWaveTrack and self.insidePart: pass else: self.currWaveTrackName = "" def checkTriggerForAdd(self, theFile, currLine): if string.find(currLine , " -1: # we're in business, add ALL stored info: # 1. AudioOutput # 2. AudioInput # 3. AudioGroup # 4. SynthI # 5. Routes # # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # adata.append([atype,name,idx,ch,conn,vol,pan,mute,solo,pre,off,p1,p2,p3,p4]) # 1. for line in adata: if line[0] == "audiomaster": #print "amaster" #print line outFile.write(" \n") outFile.write(" %s\n"%line[1]) outFile.write(" 0\n") outFile.write(" %s\n"%line[7]) outFile.write(" %s\n"%line[8]) outFile.write(" %s\n"%line[10]) outFile.write(" %s\n"%line[3]) outFile.write(" 20\n") outFile.write(" 0\n") outFile.write(" %s\n"%line[9]) outFile.write(" 1\n") outFile.write(" \n"%line[5]) outFile.write(" \n") outFile.write(" \n"%line[6]) outFile.write(" \n") if line[11] !=[]: print "%s line[11] %s"%(line[1],line[11]) for pl in line[11]: outFile.write(pl) if line[12] !=[]: print "%s line[12] %s"%(line[1],line[12]) for pl in line[12]: outFile.write(pl) if line[13] !=[]: print "%s line[13] %s"%(line[1],line[13]) for pl in line[13]: outFile.write(pl) if line[14] !=[]: print "%s line[14] %s"%(line[1],line[14]) for pl in line[14]: outFile.write(pl) outFile.write(" \n") # 2. for line in adata: if line[0] == "audioinput": outFile.write(" \n") outFile.write(" %s\n"%line[1]) outFile.write(" 0\n") outFile.write(" %s\n"%line[7]) outFile.write(" %s\n"%line[8]) outFile.write(" %s\n"%line[10]) outFile.write(" %s\n"%line[3]) outFile.write(" 20\n") outFile.write(" 0\n") outFile.write(" %s\n"%line[9]) outFile.write(" 1\n") outFile.write(" \n"%line[5]) outFile.write(" \n") outFile.write(" \n"%line[6]) outFile.write(" \n") if line[11] !=[]: print "%s line[11] %s"%(line[1],line[11]) for pl in line[11]: outFile.write(pl) if line[12] !=[]: print "%s line[12] %s"%(line[1],line[12]) for pl in line[12]: outFile.write(pl) if line[13] !=[]: print "%s line[13] %s"%(line[1],line[13]) for pl in line[13]: outFile.write(pl) if line[14] !=[]: print "%s line[14] %s"%(line[1],line[14]) for pl in line[14]: outFile.write(pl) outFile.write(" \n") # 3. for line in adata: if line[0] == "audiogroup": outFile.write(" \n") outFile.write(" %s\n"%line[1]) outFile.write(" 0\n") outFile.write(" %s\n"%line[7]) outFile.write(" %s\n"%line[8]) outFile.write(" %s\n"%line[10]) outFile.write(" %s\n"%line[3]) outFile.write(" 20\n") outFile.write(" 0\n") outFile.write(" %s\n"%line[9]) outFile.write(" 1\n") outFile.write(" \n"%line[5]) outFile.write(" \n") outFile.write(" \n"%line[6]) outFile.write(" \n") if line[11] !=[]: print "%s line[11] %s"%(line[1],line[11]) for pl in line[11]: outFile.write(pl) if line[12] !=[]: print "%s line[12] %s"%(line[1],line[12]) for pl in line[12]: outFile.write(pl) if line[13] !=[]: print "%s line[13] %s"%(line[1],line[13]) for pl in line[13]: outFile.write(pl) if line[14] !=[]: print "%s line[14] %s"%(line[1],line[14]) for pl in line[14]: outFile.write(pl) outFile.write(" \n") # 4. for line in adata: if line[0] == "synth": outFile.write(" \n") outFile.write(" %s\n"%line[1]) outFile.write(" 0\n") outFile.write(" %s\n"%line[7]) outFile.write(" %s\n"%line[8]) outFile.write(" %s\n"%line[10]) outFile.write(" %s\n"%line[3]) outFile.write(" 20\n") outFile.write(" 0\n") outFile.write(" %s\n"%line[9]) outFile.write(" 1\n") outFile.write(" \n"%line[5]) outFile.write(" \n") outFile.write(" \n"%line[6]) outFile.write(" \n") # event data for synt in synths: if synt[1] == line[1]: # we found this synth, proceed outFile.write(" %s\n"%synt[0]) outFile.write(" %s\n"%synt[2]) outFile.write(" %s\n"%synt[3]) outFile.write(" \n") if synt[0] == "fluidsynth": # Woaaahh, special treatment, do I have something for you!!!! self.processFluid(synt) else: # Other synth for state in synt[4]: for evl in state: outFile.write(evl) outFile.write(" \n") #return ([clas,name,port,guiVisible,stateInfo]) outFile.write(" \n") # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # adata.append([atype,name,idx,ch,conn,vol,pan,mute,solo,pre,off,p1,p2,p3,p4]) # 5. - create all routes for line in adata: for line2 in adata: if line[4] == line2[1]: print ">route %s line[4]=%s %s line2[1]=%s"%(line[1],line[4],line2[1],line2[1]) outFile.write(" \n") outFile.write(" %s\n"%line[1]) outFile.write(" %s\n"%line2[1]) outFile.write(" \n") else: print "-route %s line[4]=%s %s line2[1]=%s"%(line[1],line[4],line2[1],line2[1]) outFile.write(" \n") outFile.write(" 1:Master\n") outFile.write(" alsa_pcm:playback_1\n") outFile.write(" \n") outFile.write(" \n") outFile.write(" 2:Master\n") outFile.write(" alsa_pcm:playback_2\n") outFile.write(" \n") def processFluid(self, fluid): # here we go print "Fluidsynth!!" #for state in fluid[4]: # for evl in state: # outFile.write(evl) # ok, let's convert the first event outdata=" " nbrOfFonts=0 counter2f = 0 externalConnects=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] externalConnects2f=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] for event in fluid[4]: hexstr = self.convertEventToHexStr(event) print hexstr counter1 = 0 counter2 = 0 if hexstr[0] == "28": externalConnects[nbrOfFonts] = hexstr[1] nbrOfFonts = nbrOfFonts+1 for h in hexstr[2:-1]: outdata = outdata + "%s "%h counter1 == counter1 + 1 counter2 == counter2 + 1 if counter1 > 9: outdata = outdata + "\n " counter1= 0 elif hexstr[0] == "2f": # ext_id preset channel externalConnects2f[counter2f] = "%s %s %s "%(hexstr[1],hexstr[3], "00") #hexstr[2]) counter2f=counter2f+1 # translate # initStr = "f2 00 03 01 2f 00" # fluid v3 , one soundfont, lastdir= "/" outFile.write(" \n") #%(len(hex)-3)) outFile.write(" f2 00 03 0%X 2f 00\n"%nbrOfFonts) outFile.write(outdata) outFile.write("\n ff ") for i in range(nbrOfFonts): outFile.write("%s "%(externalConnects[i])) outFile.write("\n ") for ext in externalConnects2f: outFile.write(ext) outFile.write("\n 00 00 00 00 00 00 00 00\n") outFile.write(" 00 00 00 00 ff ff ff ff 00 00 00 00 00 00\n") #outFile.write(" ff 00 00 81 00 7f 81 00 7f\n") # outFile.write(" 81 00 7f 81 00 7f 81 00 7f 81 00 7f 81 00 7f 81\n") # outFile.write(" 00 7f 81 00 7f 81 00 7f 81 00 7f 81 00 7f 81 00\n") # outFile.write(" 7f 81 00 7f 81 00 7f 81 00 00 00 00 00 00 00 00\n") outFile.write(" \n") def convertEventToHexStr(self, event): # here we go newLine=[] for line in event[1:-1]: splitLine = string.split(line) nbr = len(splitLine) #print nbr #print splitLine count = 0 while count < nbr: newLine.append("%s%s"%(splitLine[count][1],splitLine[count+1][1])) count = count + 2 #print newLine return newLine def help(): print "Utility to convert MusE 0.6 songs to 0.7 or newer song format." print "Usage: muse-convert " print "" print "Please report any problems with this script to rj@spamatica.se" print "Author: Robert Jonsson, 2005, Copylefted under the GPL" ######################## # --- Main program --- # ######################## print "MusE Song converter %s"%version print "" if len(sys.argv) < 2: help() sys.exit("") print "Processing file ", sys.argv[1] print "" # step 1 - remove malformed data inFile = file(sys.argv[1]) outFile = file(sys.argv[1]+".tmp","w") fileEnd = False convert = MusEConvert() #take care of first few lines: outFile.write(inFile.readline()) # ") == -1: print "Unable to confirm that this is a song file with the old format, aborting..." sys.exit("") outFile.write("\n"%version) while fileEnd == False: line = inFile.readline() if line == "": fileEnd = True newLine = convert.fixComma(inFile,line) outFile.write(newLine) inFile.close() outFile.close() #sys.exit("") inFile = file(sys.argv[1]+".tmp","r") outFile = file(sys.argv[1]+".converted","w") fileEnd = False while fileEnd == False: line = inFile.readline() if line == "": fileEnd = True convert.checkPart(inFile,line) # only state variables convert.getWaveTrackName(inFile,line) # only state variables convert.checkTriggerForAdd(inFile,line) # insert routes+stuff? if convert.findAndSkipBlock(inFile, line) == True: pass elif convert.checkAGroup(inFile,line): pass elif convert.checkAMaster(inFile,line): pass elif convert.checkSynth(inFile,line): pass elif convert.checkAInput(inFile,line): pass #elif convert.checkMGroup(inFile,line): # pass elif convert.checkClip(inFile,line): pass elif convert.checkWaveTrack(inFile,line): # only state variables pass else: outFile.write(line) print "" print "Converted!" print ""