ayé, on joue du musicxml :-)
[minwii.git] / src / songs / musicxmltosong.py
index 00903a1..ed7dddf 100755 (executable)
@@ -9,7 +9,7 @@ import sys
 from types import StringTypes
 from xml.dom.minidom import parse
 from optparse import OptionParser
-from Song import Song
+#from Song import Song
 
 # Do4 <=> midi 60
 OCTAVE_REF = 4
@@ -20,10 +20,23 @@ DIATO_SCALE = {'C' : 60,
                'G' : 67,
                'A' : 69,
                'B' : 71}
+
+FR_NOTES = {'C' : u'Do',
+            'D' : u'Ré',
+            'E' : u'Mi',
+            'F' : u'Fa',
+            'G' : u'Sol',
+            'A' : u'La',
+            'B' : u'Si'}
+
 _marker = []
 
 class Part(object) :
     
+    requiresExtendedScale = False
+    scale = [55, 57, 59, 60, 62, 64, 65, 67, 69, 71, 72]
+    quarterNoteLength = 400
+    
     def __init__(self, node, autoDetectChorus=True) :
         self.node = node
         self.notes = []
@@ -81,13 +94,16 @@ class Part(object) :
     def iterNotes(self) :
         "exécution de la chanson avec l'alternance couplets / refrains"
         for verse in self.verses :
+            print "---partie---"
             repeats = len(verse[0].lyrics)
             if repeats > 1 :
                 for i in range(repeats) :
                     # couplet
+                    print "---couplet%d---" % i
                     for note in verse :
                         yield note, i
                     # refrain
+                    print "---refrain---"
                     for note in self.chorus :
                         yield note, 0
             else :
@@ -96,11 +112,25 @@ class Part(object) :
         
     def pprint(self) :
         for note, verseIndex in self.iterNotes() :
-            print note.name, note.midi, note.duration, note.lyrics[verseIndex]
+            print note.nom, note.name, note.midi, note.duration, note.lyrics[verseIndex]
+
+
+    def assignNotesFromMidiNoteNumbers(self):
+        # TODO faire le mapping bande hauteur midi
+        for i in range(len(self.midiNoteNumbers)):
+            noteInExtendedScale = 0
+            while self.midiNoteNumbers[i] > self.scale[noteInExtendedScale] and noteInExtendedScale < len(self.scale)-1:
+                noteInExtendedScale += 1
+            if self.midiNoteNumbers[i]<self.scale[noteInExtendedScale]:
+                noteInExtendedScale -= 1
+            self.notes.append(noteInExtendedScale)
+
         
         
 
 class Note(object) :
+    scale = [55, 57, 59, 60, 62, 64, 65, 67, 69, 71, 72]
+    
     def __init__(self, node, divisions, previous) :
         self.node = node
         self.step = _getNodeValue(node, 'pitch/step')
@@ -136,15 +166,38 @@ class Note(object) :
         name = '%s%s' % (name, abs(self.alter) * alterext)
         return name
     
+    @property
+    def nom(self) :
+        name = FR_NOTES[self.step]
+        if self.alter < 0 :
+            alterext = 'b'
+        else :
+            alterext = '#'
+        name = '%s%s' % (name, abs(self.alter) * alterext)
+        return name
+    
+    @property
+    def column(self):
+        return self.scale.index(self.midi)
+    
 
 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__
         
         
@@ -161,7 +214,7 @@ def _getNodeValue(node, path, default=_marker) :
         else :
             return default
 
-def musicXml2Song(input, output, partIndex=0, printNotes=False) :
+def musicXml2Song(input, partIndex=0, printNotes=False) :
     if isinstance(input, StringTypes) :
         input = open(input, 'r')
     
@@ -178,6 +231,9 @@ def musicXml2Song(input, output, partIndex=0, printNotes=False) :
     
     if printNotes :
         part.pprint()
+
+    return part
+
     
     # divisions de la noire
 #    divisions = 0
@@ -214,10 +270,10 @@ def main() :
     
     options, args = op.parse_args()
     
-    if len(args) != 2 :
+    if len(args) != 1 :
         raise SystemExit(op.format_help())
     
-    musicXml2Song(args[0], args[1], partIndex=options.partIndex, printNotes=options.printNotes)
+    musicXml2Song(args[0], partIndex=options.partIndex, printNotes=options.printNotes)