[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

midi2ly: Fraction Reduction + 2 minor issues

From: Christopher Heckman
Subject: midi2ly: Fraction Reduction + 2 minor issues
Date: Thu, 13 Apr 2017 17:18:38 -0700

(1) When midi2ly is run, it will print fractions with large numerators
and denominators, like

r4*361/120 e4*29/120 r4*31/120 e4*59/120 r4*361/120 e4*29/120

when the actual durations are more likely to be

r2. e4*1/4 r4*1/4 e4*1/2 r2. e4*1/4 r4*1/4 e4*1/2 r2. e4*1/4

I have written a patch to fix this. Inside of the class Duration (line
129), replace the dump function with:


    def dump (self):
        den = self.den; num = self.num;
        # code below by C C Heckman
        # looks for a neighboring fraction that reduces
        if num > 1:
            gcd1 = gcd (num - 1, den)
            gcd2 = gcd (num, den)
            gcd3 = gcd (num + 1, den)
            if gcd1 > gcd2 and gcd1 > gcd3:
                d = -1; g = gcd1
            elif gcd3 > gcd2 and gcd3 > gcd1:
                d = +1; g = gcd3
                d = 0; g = gcd2
                # for now, do nothing
            num = (num + d) / g
            den = den / g
        if den == 1:
            if num == 1:
                s = '%d' % self.dur
            elif num == 3 and self.dur != 1:
                s = '%d.' % (self.dur / 2)
                s = '%d*%d' % (self.dur, num)
            s = '%d*%d/%d' % (self.dur, num, den)
        # end modified code


This will reduce the fractions (n-1)/d, n/d, and (n+1)/d (where the
original fraction is n/d). If (n-1)/d or (n+1)/d reduces more, its
reduction replaces n/d, except in one technical case. For instance,
the fraction 29/120 is considered to be rounded off after some error
has been added. The possible values to be checked are 28/120 (7/30 in
lowest terms), 29/120 (which does not reduce), and 30/120 (1/4). Since
30/120 reduces to the smallest denominator, 29/120 gets replaced with

Now the technical case: If n/d is in lowest terms, n is odd, and d is
even but not divisible by 2, then n/d won't reduce, but you will be
able to cancel a factor of 2 from (n-1)/d and (n+1)/d. Since there is
no way to break this tie, the original value n/d is kept. (Note this
is the only case where (n-1)/d and (n+1)/d will be reduced by the same
denominator. I've proven this.)

Note that this will *not* make changes like 4*1/4 into 16; that might
be in a future version. This would turn the example output into

r2. e16 r16 e8 r2. e16 r16 e8 r2. e16

Also, fractions which don't reduce but have large denominators might
be replaced with approximations with small denominators. (Continued
fractions allow you to calculate these.)

(2) In line 181 of midi2ly.py, the authors talk about how the 7th of a
minor scale should be raised, but this is not notated. The real issue
is that there are two types of minor scale involved, the harmonic
minor (1 2 b3 4 5 b6 7) and the natural minor (1 2 b3 4 5 b6 b7). The
reason that "C# is not put in the key signature of D minor" is that
the minor scale is the natural minor, not the harmonic minor.

(3) At line 677, there's a cryptic comment

# urg, this will barf at meter changes

Is there a brief explanation of the problem available?

Christopher Carl Heckman
Honors Faculty
33° 25' 7'' N, 111° 55' 55'' W
ECA 212
School of Mathematical & Statistical Sciences
Arizona State University (T1N R4E Sect22 NW1/4)
Tempe, AZ 85287 - 1804
United States of America
North America
Planet Earth
Solar System
Gould Belt
Local Bubble
Local Fluff
Milky Way Galaxy, Orion Arm
Local Group
Virgo Supercluster
Pisces-Cetus Supercluster Complex

reply via email to

[Prev in Thread] Current Thread [Next in Thread]