--- lilypond/python/musicxml.py 2006-08-26 01:04:08.000000000 +0300 +++ musicxml.py 2006-09-17 13:23:09.000000000 +0300 @@ -1,4 +1,5 @@ import new +import math from rational import * class Xml_node: @@ -193,7 +194,33 @@ 'long': -2, 'whole': 0} [log] else: - return 0 + # Using floating point arithmetic here + # Lengthening_factor means that durations between + # quarter note * (1-lengthening factor) and + # half note * (1-lengthening factor) + # --> quarter note (return 2) + # etc. Thus rounding errors shouldn't cause problems. + + # With dot_limit=4 get_num_dots won't return more than 4, because + # for example for duration c4..... this function returns 1 (half note). + # (Floating point arithmetics can cause some randomness whether a + # note becomes c4.... or c2) + dot_limit = 4 + lengthening_factor = 1 / (1 - 2**-(dot_limit+1) ) + print self._duration*lengthening_factor + return int (math.ceil + (-math.log (self._duration*lengthening_factor) / math.log (2))) + + def get_num_dots(self): + if self.get_maybe_exist_typed_child (class_dict['type']): + return len (self.get_typed_children (Dot)) + + else: + # factor means how many times duration is the length of the base note. + # 2 - factor tells how far duration is from the next whole duration + # by rounding we can also handle weird durations in input + factor = self._duration / 2**(-self.get_duration_log()) + return int (round (-math.log(2 - factor) / math.log(2))) def get_factor (self): return 1 @@ -351,27 +378,26 @@ elements.extend (m.get_all_children ()) start_attr = None - for n in elements: - voice_id = n.get_maybe_exist_typed_child (class_dict['voice']) - - if not (voice_id or isinstance (n, Attributes)): - continue - - if isinstance (n, Attributes) and not start_attr: - start_attr = n - continue - - if isinstance (n, Attributes): - for v in voices.values (): + for n in elements: + if (isinstance (n, Note)): + voice_id = n.get_maybe_exist_typed_child (get_class('voice')) + if voice_id: + id = voice_id.get_text () + else: + id = '1' + + if not voices.has_key (id): + voices[id] = Musicxml_voice() + + voices[id].add_element (n) + + elif isinstance (n, Attributes): + if not start_attr: + start_attr = n + + for v in voices.values (): v.add_element (n) - continue - - id = voice_id.get_text () - if not voices.has_key (id): - voices[id] = Musicxml_voice() - - voices[id].add_element (n) - + if start_attr: for (k,v) in voices.items (): v.insert (0, start_attr)