Added helper python file for anaylizing tracks in MIDI files.
This commit is contained in:
parent
86f32df3ae
commit
4ecf05c098
155
scan_tracks.py
Normal file
155
scan_tracks.py
Normal file
@ -0,0 +1,155 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Scans all JSON song files and reports track information.
|
||||
Shows each track's note count to help with track selection.
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Tuple
|
||||
|
||||
|
||||
def scan_song_file(file_path: Path) -> Dict:
|
||||
"""
|
||||
Scan a single JSON song file and extract track information.
|
||||
|
||||
Returns:
|
||||
Dict with 'name', 'artist', 'tracks' (list of note counts)
|
||||
"""
|
||||
try:
|
||||
with open(file_path, 'r', encoding='utf-8') as f:
|
||||
data = json.load(f)
|
||||
|
||||
song_name = data.get('header', {}).get('name', 'Unknown')
|
||||
artist = data.get('header', {}).get('artist', 'Unknown')
|
||||
tracks = data.get('tracks', [])
|
||||
|
||||
track_info = []
|
||||
for i, track in enumerate(tracks):
|
||||
notes = track.get('notes', [])
|
||||
instrument = track.get('instrument', {})
|
||||
instrument_name = instrument.get('name', 'Unknown')
|
||||
note_count = len(notes)
|
||||
|
||||
# Only count notes in the playable MIDI range (48-83)
|
||||
playable_notes = [n for n in notes if 48 <= n.get('midi', 0) <= 83]
|
||||
playable_count = len(playable_notes)
|
||||
|
||||
track_info.append({
|
||||
'index': i,
|
||||
'instrument': instrument_name,
|
||||
'total_notes': note_count,
|
||||
'playable_notes': playable_count,
|
||||
'channel': track.get('channel', 'N/A')
|
||||
})
|
||||
|
||||
return {
|
||||
'name': song_name,
|
||||
'artist': artist,
|
||||
'tracks': track_info,
|
||||
'file': file_path.name
|
||||
}
|
||||
except Exception as e:
|
||||
return {
|
||||
'name': 'ERROR',
|
||||
'artist': str(e),
|
||||
'tracks': [],
|
||||
'file': file_path.name
|
||||
}
|
||||
|
||||
|
||||
def find_best_track(tracks: List[Dict]) -> int:
|
||||
"""Find the track with the most playable notes (mimics the game logic)."""
|
||||
if not tracks:
|
||||
return 0
|
||||
|
||||
best_idx = 0
|
||||
best_count = 0
|
||||
for i, track in enumerate(tracks):
|
||||
if track['playable_notes'] > best_count:
|
||||
best_count = track['playable_notes']
|
||||
best_idx = i
|
||||
|
||||
return best_idx
|
||||
|
||||
|
||||
def main():
|
||||
# Find the assets/songs/json directory
|
||||
script_dir = Path(__file__).parent
|
||||
json_dir = script_dir / 'assets' / 'songs' / 'json'
|
||||
|
||||
if not json_dir.exists():
|
||||
print(f"Error: Directory not found: {json_dir}")
|
||||
return
|
||||
|
||||
# Find all JSON files
|
||||
json_files = sorted(json_dir.glob('*.json'))
|
||||
|
||||
if not json_files:
|
||||
print(f"No JSON files found in {json_dir}")
|
||||
return
|
||||
|
||||
print("=" * 80)
|
||||
print("SONG TRACK ANALYSIS")
|
||||
print("=" * 80)
|
||||
print()
|
||||
|
||||
# Scan each file
|
||||
all_songs = []
|
||||
for json_file in json_files:
|
||||
song_info = scan_song_file(json_file)
|
||||
all_songs.append(song_info)
|
||||
|
||||
# Print detailed report
|
||||
for song in all_songs:
|
||||
print(f"FILE: {song['file']}")
|
||||
print(f" Song: {song['name']}")
|
||||
print(f" Artist: {song['artist']}")
|
||||
print(f" Tracks: {len(song['tracks'])}")
|
||||
|
||||
if song['tracks']:
|
||||
best_idx = find_best_track(song['tracks'])
|
||||
print()
|
||||
for track in song['tracks']:
|
||||
is_best = track['index'] == best_idx
|
||||
marker = " [AUTO-SELECTED]" if is_best else ""
|
||||
print(f" Track {track['index']}: "
|
||||
f"{track['playable_notes']:4d} playable notes "
|
||||
f"({track['total_notes']:4d} total) - "
|
||||
f"{track['instrument']}{marker}")
|
||||
else:
|
||||
print(" No tracks found!")
|
||||
|
||||
print()
|
||||
print("-" * 80)
|
||||
print()
|
||||
|
||||
# Summary statistics
|
||||
print("\n" + "=" * 80)
|
||||
print("SUMMARY")
|
||||
print("=" * 80)
|
||||
|
||||
total_songs = len(all_songs)
|
||||
total_tracks = sum(len(s['tracks']) for s in all_songs)
|
||||
avg_tracks = total_tracks / total_songs if total_songs > 0 else 0
|
||||
|
||||
print(f"Total songs: {total_songs}")
|
||||
print(f"Total tracks: {total_tracks}")
|
||||
print(f"Average tracks per song: {avg_tracks:.1f}")
|
||||
print()
|
||||
|
||||
# Show which songs would auto-select which track
|
||||
print("Auto-selection would choose:")
|
||||
for song in all_songs:
|
||||
if song['tracks']:
|
||||
best_idx = find_best_track(song['tracks'])
|
||||
best_track = song['tracks'][best_idx]
|
||||
print(f" {song['name']:40s} -> Track {best_idx} "
|
||||
f"({best_track['playable_notes']} notes, {best_track['instrument']})")
|
||||
|
||||
print()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Loading…
Reference in New Issue
Block a user