]> git.donarmstrong.com Git - lilypond.git/blob - scripts/musicxml2ly.py
a1a1def9b0fc1fc60d78256b80870d81681b97c6
[lilypond.git] / scripts / musicxml2ly.py
1 import sys
2 import re
3 import os
4
5 datadir = '@local_lilypond_datadir@'
6 if not os.path.isdir (datadir):
7         datadir = '@lilypond_datadir@'
8 if os.environ.has_key ('LILYPONDPREFIX'):
9         datadir = os.environ['LILYPONDPREFIX']
10         while datadir[-1] == os.sep:
11                 datadir = datadir[:-1]
12
13 if os.path.exists (os.path.join (datadir, 'share/lilypond/@TOPLEVEL_VERSION@/')):
14         datadir = os.path.join (datadir, 'share/lilypond/@TOPLEVEL_VERSION@/')
15 elif os.path.exists (os.path.join (datadir, 'share/lilypond/current/')):
16         datadir = os.path.join (datadir, 'share/lilypond/current/')
17
18 sys.path.insert (0, os.path.join (datadir, 'python'))
19
20 import musicxml
21 import musicexp
22 from rational import Rational
23
24 def musicxml_duration_to_lily (mxl_note):
25         d = musicexp.Duration ()
26         if mxl_note.get_maybe_exist_typed_child (musicxml.Type):
27                 d.duration_log = mxl_note.get_duration_log ()
28         else:
29                 d.factor = mxl_note._duration
30                 d.duration_log = 0
31
32         d.dots = len (mxl_note.get_typed_children (musicxml.Dot))
33         d.factor = mxl_note._duration / d.get_length ()
34
35         return d        
36         
37 def musicxml_voice_to_lily_voice (voice):
38         
39         ly_voice = []
40         ly_now = Rational (0)
41         for n in voice:
42                 if not n.__class__.__name__ == 'Note':
43                         print 'not a note?'
44                         continue
45
46                 pitch  = None
47                 duration = None
48                 
49                 mxl_pitch = n.get_maybe_exist_typed_child (musicxml.Pitch)
50                 event = None
51                 
52                 if mxl_pitch:
53                         pitch = musicxml_pitch_to_lily (mxl_pitch)
54                         event = musicexp.NoteEvent()
55                         event.pitch = pitch
56                 elif n.get_maybe_exist_typed_child (musicxml.Rest):
57                         event = musicexp.RestEvent()
58
59                 event.duration = musicxml_duration_to_lily (n)
60                 ev_chord = None
61                 if None ==  n.get_maybe_exist_typed_child (musicxml.Chord):
62                         if ly_voice:
63                                 ly_now += ly_voice[-1].get_length ()
64
65                         if ly_now <> n._when:
66                                 diff = n._when - ly_now 
67                                 if diff < Rational (0):
68                                         print 'huh: negative skip', n._when, ly_now, n._duration
69                                         diff = Rational (1,314159265)
70                                         
71                                 
72                                 skip = musicexp.SkipEvent()
73                                 skip.duration.duration_log = 0
74                                 skip.duration.factor = diff
75
76                                 evc = musicexp.EventChord ()
77                                 evc.elements.append (skip)
78                                 ly_voice.append (evc)
79                                 ly_now = n._when
80                                 
81                         ly_voice.append (musicexp.EventChord())
82                 else:
83                         pass
84                         #print 'append'
85                 ev_chord = ly_voice[-1]
86                 ev_chord.elements.append (event)
87
88
89         seq_music = musicexp.SequentialMusic()
90
91         
92         seq_music.elements = ly_voice
93         return seq_music
94
95
96 def musicxml_id_to_lily (id):
97         digits = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight',
98                   'nine', 'ten']
99         
100         for dig in digits:
101                 d = digits.index (dig) + 1
102                 dig = dig[0].upper() + dig[1:]
103                 id = re.sub ('%d' % d, dig, id)
104
105         id = re.sub  ('[^a-zA-Z]', 'X', id)
106         return id
107
108
109 def musicxml_pitch_to_lily (mxl_pitch):
110         p = musicexp.Pitch()
111         p.alteration = mxl_pitch.get_alteration ()
112         p.step = (ord (mxl_pitch.get_step ()) - ord ('A') + 7 - 2) % 7
113         p.octave = mxl_pitch.get_octave () -4
114         return p
115
116 def get_all_voices (parts):
117         all_voices = {} 
118         for p in parts:
119                 p.interpret ()
120                 p.extract_voices ()             
121                 voice_dict = p.get_voices ()
122                 
123                 for (id, voice) in voice_dict.items ():
124                         m = musicxml_voice_to_lily_voice (voice)
125                         m_name = 'Part' + p.name + 'Voice' + id
126                         m_name = musicxml_id_to_lily (m_name)
127                         all_voices[m_name] = m
128
129         return all_voices
130
131 printer = musicexp.Output_printer()
132
133
134 tree = musicxml.read_musicxml (sys.argv[1])
135 parts = tree.get_typed_children (musicxml.Part)
136
137 voices = get_all_voices (parts)
138 for  (k,v) in voices.items():
139         print '%s = \n' % k
140         v.print_ly (printer.dump)
141         printer.newline()
142         
143