Gets all rocksmith 2014 remastered songs in a directory and prints all tracks and their tunings. Made for use with tonelib jam to find songs
Needs rsrtools
| from rsrtools.files.welder import Welder | |
| from pathlib import Path | |
| import json | |
| base = "D:\Steam\steamapps\common\Rocksmith2014" | |
| blacklist = [ | |
| "gears.psarc", | |
| "static.psarc", | |
| "dependency_songcomponents.psarc", | |
| "scaleracer.psarc", | |
| "trackandfield.psarc", | |
| "featured.psarc" | |
| ] | |
| def get_all_files(path): | |
| return [str(p) for p in Path(path).rglob("*.psarc") if p.is_file() and p.name not in blacklist] | |
| def parseTuning(tuning: dict[str, int]): | |
| notes = ["C", "C#", "D", "D#", "E", "F", | |
| "F#", "G", "G#", "A", "A#", "B"] | |
| standard = ["E", "A", "D", "G", "B", "E"] | |
| result = [] | |
| for i, key in enumerate(sorted(tuning.keys())): | |
| base = notes.index(standard[i]) | |
| shift = tuning[key] | |
| new_note = notes[(base + shift) % 12] | |
| result.append(new_note) | |
| return "".join(result) | |
| keys = ["ArrangementName", "ArtistName", "SongName", "Tuning"] | |
| def validArrangement(entry): | |
| for key in keys: | |
| if key not in entry: | |
| return False | |
| return True | |
| def parseFile(path: str): | |
| print(path) | |
| with Welder(Path(path), "r") as w: | |
| hsans = [] | |
| # get manifest(s) | |
| for i in w: | |
| name = w.arc_name(i) | |
| if name.endswith(".hsan"): | |
| print(f"{i}: {name}") | |
| hsans.append(i) | |
| # read manifest(s) | |
| for i in hsans: | |
| data = w.arc_data(i) | |
| j = json.loads(data) | |
| entries = j["Entries"] | |
| for id in entries: | |
| entry = entries[id]["Attributes"] | |
| if validArrangement(entry): | |
| print(f"{entry["ArtistName"]} - {entry["SongName"]} ({entry["ArrangementName"]}): {parseTuning(entry["Tuning"])}") | |
| files = get_all_files(base) | |
| print(f"Found {len(files)} psarc files") | |
| for file in files: | |
| parseFile(file) |