From: pin Date: Fri, 5 Feb 2010 08:54:11 +0000 (+0000) Subject: Print des notes, hauteurs midi et durées. X-Git-Url: https://scm.cri.mines-paristech.fr/git/minwii.git/commitdiff_plain/c38dcf3a50e06fd1b76a0cad92bab19ee260798b?ds=sidebyside;hp=719344253552583b33d14ea672d9909b012d78bd Print des notes, hauteurs midi et durées. git-svn-id: https://svn.cri.ensmp.fr/svn/minwii/trunk@3 fe552daf-6dbe-4428-90eb-1537e0879342 --- diff --git a/src/songs/musicxmltosong.py b/src/songs/musicxmltosong.py index de8e26a..016593a 100755 --- a/src/songs/musicxmltosong.py +++ b/src/songs/musicxmltosong.py @@ -4,11 +4,87 @@ converstion d'un fichier musicxml en objet song minwii. $Id$ $URL$ """ +import sys +from types import StringTypes +from xml.dom.minidom import parse +from optparse import OptionParser +# Do4 <=> midi 60 +OCTAVE_REF = 4 +DIATO_SCALE = {'C' : 60, + 'D' : 62, + 'E' : 64, + 'F' : 65, + 'G' : 67, + 'A' : 69, + 'B' : 71} +_marker = [] + +class Note(object) : + def __init__(self, node, divisions) : + self.name = _getNodeValue(node, 'pitch/step') + self.octave = int(_getNodeValue(node, 'pitch/octave')) + self._duration = float(_getNodeValue(node, 'duration')) + self.divisions = divisions + + @property + def midi(self) : + mid = DIATO_SCALE[self.name] + mid = mid + (self.octave - OCTAVE_REF) * 12 + return mid + + @property + def duration(self) : + return self._duration / self.divisions + + + +def _getNodeValue(node, path, default=_marker) : + try : + for name in path.split('/') : + node = node.getElementsByTagName(name)[0] + return node.firstChild.nodeValue + except : + if default is _marker : + raise + else : + return default + +def musicXml2Song(input, output) : + if isinstance(input, StringTypes) : + input = open(input, 'r') + + d = parse(input) + doc = d.documentElement + + # TODO conversion préalable score-timewise -> score-partwise + assert doc.nodeName == u'score-partwise' + + parts = doc.getElementsByTagName('part') + # on suppose que la première partie est le chant + leadPart = parts[0] + + # divisions de la noire + divisions = 0 + for measureNode in leadPart.getElementsByTagName('measure') : + divisions = int(_getNodeValue(measureNode, 'attributes/divisions', divisions)) + for noteNode in measureNode.getElementsByTagName('note') : + note = Note(noteNode, divisions) + print note.name, note.octave, note.midi, note.duration + + def main() : - pass + usage = "%prog musicXmlFile.xml outputSongFile.smwi [options]" + op = OptionParser(usage) + + options, args = op.parse_args() + if len(args) != 2 : + raise SystemExit(op.format_help()) + + musicXml2Song(*args) + if __name__ == '__main__' : - main() \ No newline at end of file + sys.exit(main())