1 # -*- coding: utf-8 -*-
3 converstion d'un fichier musicxml en objet song minwii.
9 from types
import StringTypes
10 from xml
.dom
.minidom
import parse
11 from optparse
import OptionParser
16 DIATO_SCALE
= {'C' : 60,
27 def __init__(self
, node
) :
32 def _parseMusic(self
) :
35 for measureNode
in self
.node
.getElementsByTagName('measure') :
36 divisions
= int(_getNodeValue(measureNode
, 'attributes/divisions', divisions
))
37 next
= previous
= None
38 for i
, noteNode
in enumerate(measureNode
.getElementsByTagName('note')) :
39 note
= Note(noteNode
, divisions
, previous
)
40 self
.notes
.append(note
)
42 self
.notes
[i
-1].next
= note
48 for note
in self
.notes
:
49 print note
.name
, note
.midi
, note
.duration
, note
.lyrics
56 def __init__(self
, node
, divisions
, previous
) :
58 self
.step
= _getNodeValue(node
, 'pitch/step')
59 self
.octave
= int(_getNodeValue(node
, 'pitch/octave'))
60 self
.alter
= int(_getNodeValue(node
, 'pitch/alter', 0))
61 self
._duration
= float(_getNodeValue(node
, 'duration'))
63 for ly
in node
.getElementsByTagName('lyric') :
64 self
.lyrics
.append(Lyric(ly
))
66 self
.divisions
= divisions
67 self
.previous
= previous
72 mid
= DIATO_SCALE
[self
.step
]
73 mid
= mid
+ (self
.octave
- OCTAVE_REF
) * 12
74 mid
= mid
+ self
.alter
79 return self
._duration
/ self
.divisions
83 name
= '%s%d' % (self
.step
, self
.octave
)
88 name
= '%s%s' % (name
, abs(self
.alter
) * alterext
)
93 def __init__(self
, node
) :
95 self
.syllabic
= _getNodeValue(node
, 'syllabic', 'single')
96 self
.text
= _getNodeValue(node
, 'text')
99 return self
.text
.encode('utf-8')
105 def _getNodeValue(node
, path
, default
=_marker
) :
107 for name
in path
.split('/') :
108 node
= node
.getElementsByTagName(name
)[0]
109 return node
.firstChild
.nodeValue
111 if default
is _marker
:
116 def musicXml2Song(input, output
, partIndex
=0, printNotes
=False) :
117 if isinstance(input, StringTypes
) :
118 input = open(input, 'r')
121 doc
= d
.documentElement
123 # TODO conversion préalable score-timewise -> score-partwise
124 assert doc
.nodeName
== u
'score-partwise'
126 parts
= doc
.getElementsByTagName('part')
127 leadPart
= parts
[partIndex
]
129 part
= Part(leadPart
)
134 # divisions de la noire
136 # midiNotes, durations, lyrics = [], [], []
138 # for measureNode in leadPart.getElementsByTagName('measure') :
139 # divisions = int(_getNodeValue(measureNode, 'attributes/divisions', divisions))
140 # for noteNode in measureNode.getElementsByTagName('note') :
141 # note = Note(noteNode, divisions)
143 # print note.name, note.midi, note.duration, note.lyric
144 # midiNotes.append(note.midi)
145 # durations.append(note.duration)
146 # lyrics.append(note.lyric)
149 # midiNoteNumbers = midiNotes,
150 # noteLengths = durations,
152 # notesInExtendedScale=None)
157 usage
= "%prog musicXmlFile.xml outputSongFile.smwi [options]"
158 op
= OptionParser(usage
)
159 op
.add_option("-i", "--part-index", dest
="partIndex"
161 , help = "Index de la partie qui contient le champ.")
162 op
.add_option("-p", '--print', dest
='printNotes'
163 , action
="store_true"
165 , help = "Affiche les notes sur la sortie standard (debug)")
167 options
, args
= op
.parse_args()
170 raise SystemExit(op
.format_help())
172 musicXml2Song(args
[0], args
[1], partIndex
=options
.partIndex
, printNotes
=options
.printNotes
)
176 if __name__
== '__main__' :