view abcrange.py @ 370:ecc62b487e57 build-default-165

Some empty "" chords may be causing trouble with Jenkins. Jenkins builds are stalling when generating PDFs for some morris tunes. I suspect the problem may be an empty chord "" and abc2abc's attempt to transpose it. I've been meaning to remove the chords from the horn output, because abc2abc transposes them too, which renders them not terribly useful. So get on and do it. Also remove "" from the morris tunes where it occurs.
author Jim Hague <jim.hague@acm.org>
date Wed, 28 Aug 2013 14:57:11 +0100
parents b4a0161e8870
children 1b79867b4f35
line wrap: on
line source

#!/usr/bin/env python
#
# Find the range of a tune. Do minimal parsing of an ABC input file
# and print the lowest and highest notes therein. Accidentals are
# ignored.
#
# The output is given in purely numeric form, to avoid needing to
# re-parse it in an external script. A single line is printed with
# the highest note followed by a space and the lowest note. Middle C ('C') is
# 100. D an octave about ('d') is 108. D an octave above that ('d'') is
# 205. D below middle C ('d,') is 94. And so on.
#
# For example:
# $./abcrange.py choon.abc
# choon.abc: 112 97
#

import sys

def process(filename, inf):
    highest = 0
    lowest = 1000
    for line in inf:
        line = line.strip()
        # If it is empty or starts "%", ignore it.
        if len(line) == 0 or line[0] == "%":
            continue

        # Is it a header line? I.e. does it start LETTER COLON?
        # If so, ignore.
        start = line[:2]
        if len(start) > 1 and start[1] == ":" and start[0].isalpha():
            continue

        # Tune line.
        inchord = False
        note = 0
        notevals = {
            "C": 100,
            "D": 101,
            "E": 102,
            "F": 103,
            "G": 104,
            "A": 105,
            "B": 106,
            "c": 107,
            "d": 108,
            "e": 109,
            "f": 110,
            "g": 111,
            "a": 112,
            "b": 113,
        }
        for c in line:
            if c == "," and note > 0:
                note = note - 7
                continue
            elif c == "'" and note > 0:
                note = note + 7
                continue

            if note > 0:
                if note > highest:
                    highest = note
                if note < lowest:
                    lowest = note
                note = 0

            if c == '"':
                inchord = not inchord
                continue
            if inchord:
                continue

            if c in notevals:
                note = notevals[c]

        if note > 0:
            if note > highest:
                highest = note
            if note < lowest:
                lowest = note
            note = 0

    print "{0}: {1} {2}".format(filename, highest, lowest)

if len(sys.argv) > 1:
    for arg in sys.argv[1:]:
        try:
            inf = open(arg, "r")
            process(arg, inf)
        finally:
            inf.close()
else:
    process("stdin", sys.stdin)