123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- # converts XML files from Milan Zamazal's Singing Computer to UTAU format
- import sys
- from xml.dom.minidom import parse
- from xml.dom import minidom
- def splitNote(n,sep):
- a = ""
- b = ""
- l = []
- for c in n:
- if c in sep:
- a += c
- l += [b]
- b = ""
- else:
- b += c
- l += [b]
- return a,l
- def convertPitch(pitch):
- pitch = pitch.lower()
- octave = ""
- step = ""
- steps = {"c": 0, "c#": 1, "d": 2, "d#": 3, "e": 4,
- "f": 5, "f#": 6, "g": 7, "g#": 8, "a": 9,"a#": 10, "b": 11}
- for p in pitch:
- if p in "1234567890":
- octave += p
- if p in "abcdefg#":
- step += p
- pitch = steps[step]+12*int(octave)
- return str(pitch)
- class Note:
- def __init__(self,lyric,length,pitch):
- self.lyric = lyric
- self.length = length
- self.pitch = pitch
- class Score:
- def __init__(self,filename):
- self.notes = []
- self.bpm = 120.0
- self.utau = "DEFAULT"
- self.pos = 0
- dom = parse(filename)
- singing = dom.getElementsByTagName('SINGING')[0]
- utau = singing.getAttribute("UTAU")
- bpm = singing.getAttribute("BPM")
- if(len(bpm)):
- self.bpm = float(bpm)
- if(len(utau)):
- self.utau = utau
- nodes = singing.childNodes
- #filter nodes
- nodes = [item for item in nodes if
- item.nodeType == minidom.Node.ELEMENT_NODE]
- for element in nodes:
- self.addElement(element)
- def addElement(self,element):
- if(element.localName=="REST"):
- self.addRest(element)
- else:
- self.addNote(element)
- def addRest(self,element):
- beats = element.getAttribute("BEATS")
- beats = float(beats)
- self.notes += [Note("R",beats,"")]
- length = beats*60/self.bpm
- self.pos += length
- def addNote3(self,lyric,dur,pit):
- beats = float(dur)
- self.notes += [Note(lyric,beats,pit)]
- length = beats*60/self.bpm
- self.pos += length
- def addNote(self,element):
- pitch_note = None
- duration_beats = None
- lyric = None
- if(element.localName=="DURATION"):
- inner = element.getElementsByTagName('PITCH')[0]
- pitch_note = inner.getAttribute("NOTE")
- duration_beats = element.getAttribute("BEATS")
- lyric = inner.firstChild.data
- elif(element.localName=="PITCH"):
- inner = element.getElementsByTagName('DURATION')[0]
- pitch_note = element.getAttribute("NOTE")
- duration_beats = inner.getAttribute("BEATS")
- lyric = inner.firstChild.data
- sep1, pit = splitNote(pitch_note,",+")
- sep2, dur = splitNote(duration_beats,",+")
- assert(sep1==sep1)
- lyrics = [lyric]
- for c in sep1:
- lyrics += [c]
- assert(len(lyrics)==len(pit))
- assert(len(lyrics)==len(dur))
- for i in range(len(lyrics)):
- self.addNote3(lyrics[i],dur[i],pit[i])
- def toUST(self):
- ust = []
- ust += ["[#SETTING]"]
- ust += ["Tempo="+str(self.bpm)]
- for i in range(len(self.notes)):
- s = str(i)
- fill = "0"*(4-len(s))
- ust += ["[#"+fill+s+"]"]
- n = self.notes[i]
- ust += ["Lyric="+n.lyric]
- ust += ["Length="+str(int(n.length*480))]
- ust += ["NoteNum="+convertPitch(n.pitch)]
- ust += ["[#TRACKEND]"]
- return ust
|