Mercurial > dottes
view abcrange.py @ 351:6bcafbfac674 build-default-156
Now fix logic error in makeHornInF.sh.
And we get some playable tunes. We might be able to improve the transposition
further by taking the Cello approach of calculating the minimum distance outside
the comfortable range. One for the future.
author | Jim Hague <jim.hague@acm.org> |
---|---|
date | Tue, 13 Aug 2013 01:48:21 +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)