X-Git-Url: https://scm.cri.mines-paristech.fr/git/minwii.git/blobdiff_plain/300e41c1bf5fa8a5ff38db74396174a8f7f93bb7..fd65a4ebf95a4ab4921dea29d8f578e5301a61a3:/src/songs/musicxmltosong.py diff --git a/src/songs/musicxmltosong.py b/src/songs/musicxmltosong.py index 826363e..d24d81a 100755 --- a/src/songs/musicxmltosong.py +++ b/src/songs/musicxmltosong.py @@ -41,6 +41,7 @@ class Part(object) : def __init__(self, node, autoDetectChorus=True) : self.node = node self.notes = [] + self.repeats = [] self._parseMusic() self.verses = [[]] self.chorus = [] @@ -50,25 +51,35 @@ class Part(object) : def _parseMusic(self) : divisions = 0 - noteIndex = 0 - next = previous = None + previous = None + for measureNode in self.node.getElementsByTagName('measure') : + measureNotes = [] + + # iteration sur les notes # divisions de la noire divisions = int(_getNodeValue(measureNode, 'attributes/divisions', divisions)) for noteNode in measureNode.getElementsByTagName('note') : note = Note(noteNode, divisions, previous) if not note.isRest : - self.notes.append(note) - try : - self.notes[noteIndex-1].next = note - except IndexError: - pass + measureNotes.append(note) + if previous : + previous.next = note else : previous.addDuration(note) continue - previous = note - noteIndex += 1 + self.notes.extend(measureNotes) + + # barres de reprises + try : + barlineNode = measureNode.getElementsByTagName('barline')[0] + except IndexError : + continue + + barline = Barline(barlineNode, measureNotes) + if barline.repeat : + self.repeats.append(barline) def _findChorus(self): """ le refrain correspond aux notes pour lesquelles @@ -99,7 +110,7 @@ class Part(object) : def iterNotes(self) : "exécution de la chanson avec l'alternance couplets / refrains" - for verse in self.verses : + for verse in cycle(self.verses) : print "---partie---" repeats = len(verse[0].lyrics) if repeats > 1 : @@ -118,7 +129,7 @@ class Part(object) : def pprint(self) : for note, verseIndex in self.iterNotes() : - print note.nom, note.name, note.midi, note.duration, note.lyrics[verseIndex] + print note, note.lyrics[verseIndex] def assignNotesFromMidiNoteNumbers(self): @@ -131,7 +142,35 @@ class Part(object) : noteInExtendedScale -= 1 self.notes.append(noteInExtendedScale) - + +class Barline(object) : + + def __init__(self, node, measureNotes) : + self.node = node + location = self.location = node.getAttribute('location') or 'right' + try : + repeatN = node.getElementsByTagName('repeat')[0] + repeat = {'direction' : repeatN.getAttribute('direction'), + 'times' : int(repeatN.getAttribute('times') or 1)} + if location == 'left' : + repeat['note'] = measureNotes[0] + elif location == 'right' : + repeat['note'] = measureNotes[-1] + else : + raise ValueError(location) + self.repeat = repeat + except IndexError : + self.repeat = None + + def __str__(self) : + if self.repeat : + if self.location == 'left' : + return '|:' + elif self.location == 'right' : + return ':|' + return '|' + + __repr__ = __str__ class Note(object) : @@ -158,6 +197,12 @@ class Note(object) : self.previous = previous self.next = None + def __str__(self) : + return (u'%5s %2s %2d %4s' % (self.nom, self.name, self.midi, round(self.duration, 2))).encode('utf-8') + + def __repr__(self) : + return self.name.encode('utf-8') + def addDuration(self, note) : self._duration = self.duration + note.duration self.divisions = 1 @@ -212,9 +257,12 @@ class Lyric(object) : self.syllabic = _getNodeValue(node, 'syllabic', 'single') self.text = _getNodeValue(node, 'text') - def __str__(self) : + def syllabus(self, encoding='utf-8'): text = self._syllabicModifiers[self.syllabic] % self.text - return text.encode('utf-8') + return text.encode(encoding) + + def __str__(self) : + return self.syllabus() __repr__ = __str__