+++ /dev/null
-# -*- coding: utf-8 -*-
-"""
-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
-from Song import Song
-
-# 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.step = _getNodeValue(node, 'pitch/step')
- self.octave = int(_getNodeValue(node, 'pitch/octave'))
- self.alter = int(_getNodeValue(node, 'pitch/alter', 0))
- self._duration = float(_getNodeValue(node, 'duration'))
- self.lyric = _getNodeValue(node, 'lyric/text', '')
-
- self.divisions = divisions
-
- @property
- def midi(self) :
- mid = DIATO_SCALE[self.step]
- mid = mid + (self.octave - OCTAVE_REF) * 12
- mid = mid + self.alter
- return mid
-
- @property
- def duration(self) :
- return self._duration / self.divisions
-
- @property
- def name(self) :
- name = '%s%d' % (self.step, self.octave)
- if self.alter < 0 :
- alterext = 'b'
- else :
- alterext = '#'
- name = '%s%s' % (name, abs(self.alter) * alterext)
- return name
-
-
-
-
-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, partIndex=0, printNotes=False) :
- 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')
- leadPart = parts[partIndex]
-
- # divisions de la noire
- divisions = 0
- midiNotes, durations, lyrics = [], [], []
-
- for measureNode in leadPart.getElementsByTagName('measure') :
- divisions = int(_getNodeValue(measureNode, 'attributes/divisions', divisions))
- for noteNode in measureNode.getElementsByTagName('note') :
- note = Note(noteNode, divisions)
- if printNotes :
- print note.name, note.midi, note.duration, note.lyric
- midiNotes.append(note.midi)
- durations.append(note.duration)
- lyrics.append(note.lyric)
-
- song = Song(None,
- midiNoteNumbers = midiNotes,
- noteLengths = durations,
- lyrics = lyrics,
- notesInExtendedScale=None)
- song.save(output)
-
-
-def main() :
- usage = "%prog musicXmlFile.xml outputSongFile.smwi [options]"
- op = OptionParser(usage)
- 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)")
-
- options, args = op.parse_args()
-
- if len(args) != 2 :
- raise SystemExit(op.format_help())
-
- musicXml2Song(args[0], args[1], partIndex=options.partIndex, printNotes=options.printNotes)
-
-
-
-if __name__ == '__main__' :
- sys.exit(main())