X-Git-Url: https://svn.cri.ensmp.fr/git/minwii.git/blobdiff_plain/f3c7ce6115ca54c1bc5db03ce03a873ee379edcf..27f0459072ce2077d73bc95e95b4dc52af86147c:/src/songs/musicxmltosong.py?ds=inline diff --git a/src/songs/musicxmltosong.py b/src/songs/musicxmltosong.py index ed7dddf..91feeae 100755 --- a/src/songs/musicxmltosong.py +++ b/src/songs/musicxmltosong.py @@ -9,6 +9,7 @@ import sys from types import StringTypes from xml.dom.minidom import parse from optparse import OptionParser +from itertools import cycle #from Song import Song # Do4 <=> midi 60 @@ -49,20 +50,24 @@ class Part(object) : def _parseMusic(self) : divisions = 0 - noteIndex = 0 - next = previous = None + previous = None + for measureNode in self.node.getElementsByTagName('measure') : + measureNotes = [] # divisions de la noire divisions = int(_getNodeValue(measureNode, 'attributes/divisions', divisions)) for noteNode in measureNode.getElementsByTagName('note') : note = Note(noteNode, divisions, previous) - self.notes.append(note) - try : - self.notes[noteIndex-1].next = note - except IndexError: - pass + if not note.isRest : + measureNotes.append(note) + if previous : + previous.next = note + else : + previous.addDuration(note) + continue previous = note - noteIndex += 1 + + self.notes.extend(measureNotes) def _findChorus(self): """ le refrain correspond aux notes pour lesquelles @@ -112,7 +117,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): @@ -125,6 +130,19 @@ class Part(object) : noteInExtendedScale -= 1 self.notes.append(noteInExtendedScale) + +class Barline(object) : + + def __init__(self, node) : + self.node = node + self.location = node.getAttribute('location') + try : + repeat = node.getElementsByTagName('repeat')[0] + repeat = {'direction' : repeat.getAttribute('direction'), + 'times' : int(repeat.getAttribute('times') or 1)} + self.repeat = repeat + except IndexError : + self.repeat = None @@ -133,9 +151,16 @@ class Note(object) : def __init__(self, node, divisions, previous) : self.node = node - self.step = _getNodeValue(node, 'pitch/step') - self.octave = int(_getNodeValue(node, 'pitch/octave')) - self.alter = int(_getNodeValue(node, 'pitch/alter', 0)) + self.isRest = False + self.step = _getNodeValue(node, 'pitch/step', None) + if self.step is not None : + self.octave = int(_getNodeValue(node, 'pitch/octave')) + self.alter = int(_getNodeValue(node, 'pitch/alter', 0)) + elif self.node.getElementsByTagName('rest') : + self.isRest = True + else : + NotImplementedError(self.node.toxml('utf-8')) + self._duration = float(_getNodeValue(node, 'duration')) self.lyrics = [] for ly in node.getElementsByTagName('lyric') : @@ -145,6 +170,16 @@ 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 + @property def midi(self) : mid = DIATO_SCALE[self.step]