diff --git a/stt.py b/stt.py index c833f27..fde3fc7 100755 --- a/stt.py +++ b/stt.py @@ -9,14 +9,42 @@ import json mydir = os.path.dirname(os.path.realpath(__file__)) +# Lookup value is value of note for ( string * 1000 ) + value of fret +lookuptable = { + 57: ["Cr", "x"], + 49: ["Cr", "x"], + "XX": ["Hh", "x"], + 51: ["Ri", "x"], + 3048: ["HT", "o"], + 3047: ["MT", "o"], + 4038: ["Sn", "o"], + 3043: ["FT", "o"], + 5035: ["Bd", "o"], + 44: ["Hf", "x"] +} + +### DrumBurp notation Wikipedia notation Wikipedia notation +### Cr - Crash Drums Cymbals +### Hh - HiHat |-o-| Strike |-x-| Strike cymbal or hi-hat +### Ri - Ride |-O-| Accent |-X-| Strike loose hi-hat, or hit crash hard +### HT - High Tom |-g-| Ghost note |-o-| Open hi-hat +### MT - Mid Tom |-f-| Flam |-#-| Choke cymbal (grab cymbal with hand after striking it) +### Sn - Snare |-d-| Drag |-s-| Splash cymbal +### FT - Floor Tom |-b-| Soft one-handed roll |-c-| China cymbal +### Bd - Kick |-B-| Accented one-handed roll |-b-| Bell of ride +### Hf - Foot pedal |-@-| Snare rim |-x-| Click hi-hat with foot +### DrumBurp: https://whatang.org/ +### Wikipedia: https://en.wikipedia.org/wiki/Drum_tablature + def commandline(): # initiate the parser - parser = argparse.ArgumentParser(description="Awesome tool to...") + parser = argparse.ArgumentParser(description="Make ASCII tabs from songsterr tabs.") # option without argument via 'store_true' parser.add_argument("-V", "--version", help="show program version", action="store_true") # option with argument - parser.add_argument("--width", "-w", help="set output width") + parser.add_argument("--width", "-w", help="set output width in measures") parser.add_argument("--input", "-i", help="set input file") + parser.add_argument("--url", "-u", help="set input url") # read arguments from the command line args = parser.parse_args() @@ -24,10 +52,18 @@ def commandline(): # handle arguments # check for --version or -V if args.version: - print("this is myprogram version 0.1") + print("Version 0.1") # check for --width if args.width: print("set output width to %s" % args.width) + if args.url: + print("url not handled yet %s" % args.width) + if args.input and args.url: + print("Give either a url, or an input file, not both.") + exit() + if not args.input and not args.url: + print("Give either a url, or an input file.") + exit() return args @@ -40,81 +76,23 @@ def get_json(html): print("Can't find the magic") return data -args = commandline() +def print_meta(jsondata): + print( "Artist: " + jsondata["meta"]["artist"] ) + print( "Title: " + jsondata["meta"]["title"] ) + print( "Instrument: " + jsondata["data"]["part"]["instrument"] ) + print( "BPM: " + str( jsondata["data"]["part"]["measures"][0]["voices"][0]["beats"][0]["tempo"]["bpm"] ) ) + print("") -with open(args.input, 'r') as content_file: - content = content_file.read() + return -jsondata = get_json(content) -print( "Artist: " + jsondata["meta"]["artist"] ) -print( "Title: " + jsondata["meta"]["title"] ) -print( "Instrument: " + jsondata["data"]["part"]["instrument"] ) -print( "BPM: " + str( jsondata["data"]["part"]["measures"][0]["voices"][0]["beats"][0]["tempo"]["bpm"] ) ) - -# Index: -# CC1 Crash Cymbal 1 { "string": 0, "fret": 49 } -# CC2 Crash Cymbal 2 { "string": 0, "fret": 57 } -# RC Ride Cymbal { "string": 0, "fret": 51 } - -# HMT Hi-Mid Tom { "string": 3, "fret": 48 } -# FT Floor Tom { "string": 3, "fret": 43 } -# LMT Low-Mid Tom { "string": 3, "fret": 47 } - -# S Snare { "string": 4, "fret": 38 } -# BD Bass Drum { "string": 5, "fret": 35 } -# fH Foot Hi Hat { "string": 0, "fret": 44 } - -### CC|-Crash cymbal----| -### HH|-Hi-hat----------| -### Rd|-Ride cymbal-----| -### SN|-Snare-drum------| Wikipedia notation -### T1|-High-tom--------| -### T2|-Low-tom---------| -### FT|-Floor-tom-------| -### BD |-Bass-drum------| -### Hf/FH|-Hi-hat-w/foot| - -### Cr - Crash DrumBurp notation -### Hh - HiHat -### Ri - Ride -### HT - High Tom -### MT - Mid Tom -### Sn - Snare -### FT - Floor Tom -### Bd - Kick -### Hf - Foot pedal - -### -###Cymbals -### -### |-x-| Strike cymbal or hi-hat -### |-X-| Strike loose hi-hat, or hit crash hard -### |-o-| Open hi-hat -### |-#-| Choke cymbal (grab cymbal with hand after striking it) -### |-s-| Splash cymbal -### |-c-| China cymbal -### |-b-| Bell of ride -### |-x-| Click hi-hat with foot -### -###Drums -### -### |-o-| Strike -### |-O-| Accent -### |-g-| Ghost note -### |-f-| Flam -### |-d-| Drag -### |-b-| Soft one-handed roll -### |-B-| Accented one-handed roll -### |-@-| Snare rim - -def get_fill(tp, typelength): +def get_skip(tp, typelength): if tp < typelength: - fill = "-" * int( ( typelength / tp ) - 1 ) + skip = int( ( typelength / tp ) ) else: - fill = "" + skip = 1 - return fill + return skip def get_typelength(jsondata): typelength = 0 @@ -125,40 +103,68 @@ def get_typelength(jsondata): typelength = beat["type"] return typelength -print("") -print( str( jsondata["data"]["part"]["measures"][5]["voices"][0]["beats"] ) ) -print( "Type: " + str( jsondata["data"]["part"]["measures"][5]["voices"][0]["beats"][0]["type"] ) ) -print("") +def parse_instruments(jsondata): +# In the end I want an array of measures for each instrument +# That'll make for easy printing -# get longest type in song -typelength = get_typelength(jsondata) -print("Typelength: " + str(typelength)) -print("") + instruments = { + "Cr": [], + "Hh": [], + "Ri": [], + "HT": [], + "MT": [], + "Sn": [], + "FT": [], + "Bd": [], + "Hf": [] + } -for i in range(len(jsondata["data"]["part"]["measures"][5]["voices"][0]["beats"])): - beat = jsondata["data"]["part"]["measures"][5]["voices"][0]["beats"][i] - #print( str(i+1) + " note " + str( jsondata["data"]["part"]["measures"][5]["voices"][0]["beats"][i]["notes"] ) ) - #print("Beat: " + str(beat)) - #print("Type: " + str(beat["type"])) - fill = get_fill(beat["type"], typelength) - #print("Notes: " + str(beat["notes"])) - for note in beat["notes"]: - if note == { "string": 0, "fret": 57 } or note == { "string": 0, "fret": 49 }: - print("Cr " + "x" + fill) - elif note == { "string": 0, "fret": 51 }: - print("Ri " + "o" + fill) - elif note == { "string": 4, "fret": 38 }: - print("Sn " + "o" + fill) - elif note == { "string": 5, "fret": 35 }: - print("Bd " + "o" + fill) - elif note == { "string": 0, "fret": 44 }: - print("fH " + "o" + fill) - elif note == {'rest': True}: - print("-" + fill) - else: - print(note) + typelength = get_typelength(jsondata) + #print("Typelength: " + str(typelength)) + #print("") -# Sn ------------oooo -# Bd o-------o------- + + for measurecnt in range(len(jsondata["data"]["part"]["measures"])): + count = 0 + + # add one measure to each instrument + for instr in ["Cr", "Hh", "Ri", "HT", "MT", "Sn", "FT", "Bd", "Hf"]: + instruments[instr].append([]) + for i in range(typelength): + instruments[instr][-1].append("-") + + for beatcnt in range(len(jsondata["data"]["part"]["measures"][measurecnt]["voices"][0]["beats"])): + beat = jsondata["data"]["part"]["measures"][measurecnt]["voices"][0]["beats"][beatcnt] + skip = get_skip(beat["type"], typelength) + + for note in beat["notes"]: + if note != {'rest': True}: + lookupval = ( note["string"] * 1000 ) + note["fret"] + inst, marker = lookuptable[lookupval] + #print(measurecnt, inst, count) + if inst != None: + instruments[inst][-1][count] = marker + else: + print("Unhandled: " + note + " in measure " + str(measurecnt+1)) + print("Add: " + str(( note["string"] * 1000 ) + note["fret"]) + " to lookuptable") + count += skip + + return instruments + +def print_instruments(instruments): + for instr in ["Cr", "Hh", "Ri", "HT", "MT", "Sn", "FT", "Bd", "Hf"]: + for i in range(len(instruments["Cr"])): + print(instr + " " + "".join(instruments[instr][i])) + +args = commandline() + +with open(args.input, 'r') as content_file: + content = content_file.read() + +jsondata = get_json(content) +print_meta(jsondata) + +instr = parse_instruments(jsondata) +print_instruments(instr)