self.notes = []
self.repeats = []
self.distinctNotes = []
+ self.quarterNoteDuration = 500
self._parseMusic()
self.verses = [[]]
self.chorus = []
divisions = int(_getNodeValue(measureNode, 'attributes/divisions', divisions))
for noteNode in measureNode.getElementsByTagName('note') :
note = Note(noteNode, divisions, previous)
- if not note.isRest :
+ if (not note.isRest) and (not note.tiedStop) :
measureNotes.append(note)
if previous :
previous.next = note
+ elif note.tiedStop :
+ assert previous.tiedStart
+ previous.addDuration(note)
+ continue
else :
previous.addDuration(note)
continue
self.repeats.append(barline)
self.distinctNotes.sort(lambda a, b : cmp(a.midi, b.midi))
+ sounds = self.node.getElementsByTagName('sound')
+ tempo = 120
+ for sound in sounds :
+ if sound.hasAttribute('tempo') :
+ tempo = float(sound.getAttribute('tempo'))
+ break
+
+ self.quarterNoteDuration = int(round(60000/tempo))
+
def _findChorus(self):
elif start is not None and ll > 1 :
stop = i
break
- self.chorus = self.notes[start:stop]
+ if not (start or stop) :
+ self.chorus = []
+ else :
+ self.chorus = self.notes[start:stop]
def _findVersesLoops(self) :
"recherche des couplets / boucles"
def iterNotes(self, indefinitely=True) :
"exécution de la chanson avec l'alternance couplets / refrains"
- print 'indefinitely', indefinitely
if indefinitely == False :
iterable = self.verses
else :
iterable = cycle(self.verses)
for verse in iterable :
- print "---partie---"
+ #print "---partie---"
repeats = len(verse[0].lyrics)
if repeats > 1 :
for i in range(repeats) :
# couplet
- print "---couplet%d---" % i
+ #print "---couplet%d---" % i
for note in verse :
yield note, i
# refrain
- print "---refrain---"
+ #print "---refrain---"
for note in self.chorus :
yield note, 0
else :
@property
def name(self) :
- name = '%s%d' % (self.step, self.octave)
+ name = u'%s%d' % (self.step, self.octave)
if self.alter < 0 :
alterext = 'b'
else :
def nom(self) :
name = FR_NOTES[self.step]
if self.alter < 0 :
- alterext = 'b'
+ alterext = u'♭'
else :
- alterext = '#'
- name = '%s%s' % (name, abs(self.alter) * alterext)
+ alterext = u'#'
+ name = u'%s%s' % (name, abs(self.alter) * alterext)
return name
def __init__(self, node, divisions, previous) :
self.node = node
self.isRest = False
+ self.tiedStart = False
+ self.tiedStop = False
+
+ tieds = _getElementsByPath(node, 'notations/tied', [])
+ for tied in tieds :
+ if tied.getAttribute('type') == 'start' :
+ self.tiedStart = True
+ elif tied.getAttribute('type') == 'stop' :
+ self.tiedStop = True
+
self.step = _getNodeValue(node, 'pitch/step', None)
if self.step is not None :
self.octave = int(_getNodeValue(node, 'pitch/octave'))
class Lyric(object) :
_syllabicModifiers = {
- 'single' : '%s',
- 'begin' : '%s -',
- 'middle' : '- %s -',
- 'end' : '- %s'
+ 'single' : u'%s',
+ 'begin' : u'%s -',
+ 'middle' : u'- %s -',
+ 'end' : u'- %s'
}
def __init__(self, node) :
self.syllabic = _getNodeValue(node, 'syllabic', 'single')
self.text = _getNodeValue(node, 'text')
- def syllabus(self, encoding='utf-8'):
+ def syllabus(self):
text = self._syllabicModifiers[self.syllabic] % self.text
- return text.encode(encoding)
+ return text
def __str__(self) :
- return self.syllabus()
+ return self.syllabus().encode('utf-8')
__repr__ = __str__
else :
return default
-def musicXml2Song(input, partIndex=0, printNotes=False) :
+def _getElementsByPath(node, path, default=_marker) :
+ try :
+ parts = path.split('/')
+ for name in parts[:-1] :
+ node = node.getElementsByTagName(name)[0]
+ return node.getElementsByTagName(parts[-1])
+ except IndexError :
+ if default is _marker :
+ raise
+ else :
+ return default
+
+def musicXml2Song(input, partIndex=0, autoDetectChorus=True, printNotes=False) :
if isinstance(input, StringTypes) :
input = open(input, 'r')
parts = doc.getElementsByTagName('part')
leadPart = parts[partIndex]
- part = Part(leadPart)
+ part = Part(leadPart, autoDetectChorus=autoDetectChorus)
if printNotes :
part.pprint()
op.add_option("-i", "--part-index", dest="partIndex"
, default = 0
, help = "Index de la partie qui contient le champ.")
+
op.add_option("-p", '--print', dest='printNotes'
, action="store_true"
, default = False
, help = "Affiche les notes sur la sortie standard (debug)")
+
+ op.add_option("-c", '--no-chorus', dest='autoDetectChorus'
+ , action="store_false"
+ , default = True
+ , help = "désactive la détection du refrain")
+
options, args = op.parse_args()
if len(args) != 1 :
raise SystemExit(op.format_help())
- musicXml2Song(args[0], partIndex=options.partIndex, printNotes=options.printNotes)
-
+ musicXml2Song(args[0],
+ partIndex=options.partIndex,
+ autoDetectChorus=options.autoDetectChorus,
+ printNotes=options.printNotes)
if __name__ == '__main__' :