class Part(object) :
- def __init__(self, node) :
+ def __init__(self, node, autoDetectChorus=True) :
self.node = node
self.notes = []
self._parseMusic()
+ self.verses = [[]]
+ self.chorus = []
+ if autoDetectChorus :
+ self._findChorus()
+ self._findVersesLoops()
def _parseMusic(self) :
divisions = 0
-
+ noteIndex = 0
+ next = previous = None
for measureNode in self.node.getElementsByTagName('measure') :
+ # divisions de la noire
divisions = int(_getNodeValue(measureNode, 'attributes/divisions', divisions))
- next = previous = None
- for i, noteNode in enumerate(measureNode.getElementsByTagName('note')) :
+ for noteNode in measureNode.getElementsByTagName('note') :
note = Note(noteNode, divisions, previous)
self.notes.append(note)
try :
- self.notes[i-1].next = note
+ self.notes[noteIndex-1].next = note
except IndexError:
pass
previous = note
+ noteIndex += 1
+
+ def _findChorus(self):
+ """ le refrain correspond aux notes pour lesquelles
+ il n'existe q'une seule syllable attachée.
+ """
+ start = stop = None
+ for i, note in enumerate(self.notes) :
+ ll = len(note.lyrics)
+ if start is None and ll == 1 :
+ start = i
+ elif start is not None and ll > 1 :
+ stop = i
+ break
+ self.chorus = self.notes[start:stop]
+
+ def _findVersesLoops(self) :
+ "recherche des couplets / boucles"
+ verse = self.verses[0]
+ for note in self.notes[:-1] :
+ verse.append(note)
+ ll = len(note.lyrics)
+ nll = len(note.next.lyrics)
+ if ll != nll :
+ verse = []
+ self.verses.append(verse)
+ verse.append(self.notes[-1])
+
+ def iterNotes(self) :
+ "exécution de la chanson avec l'alternance couplets / refrains"
+ for verse in self.verses :
+ repeats = len(verse[0].lyrics)
+ if repeats > 1 :
+ for i in range(repeats) :
+ # couplet
+ for note in verse :
+ yield note, i
+ # refrain
+ for note in self.chorus :
+ yield note, 0
+ else :
+ for note in verse :
+ yield note, 0
+
def pprint(self) :
- for note in self.notes :
- print note.name, note.midi, note.duration, note.lyrics
-
-
+ for note, verseIndex in self.iterNotes() :
+ print note.name, note.midi, note.duration, note.lyrics[verseIndex]
class Lyric(object) :
+
+ _syllabicModifiers = {
+ 'single' : '%s',
+ 'begin' : '%s -',
+ 'middle' : '- %s -',
+ 'end' : '- %s'
+ }
+
def __init__(self, node) :
self.node = node
self.syllabic = _getNodeValue(node, 'syllabic', 'single')
self.text = _getNodeValue(node, 'text')
def __str__(self) :
- return self.text.encode('utf-8')
+ text = self._syllabicModifiers[self.syllabic] % self.text
+ return text.encode('utf-8')
__repr__ = __str__