Tune chord detection - less aggressive filtering
Browse files- hop_length: 2048 → 1024 (finer ~46ms resolution)
- smoothing: 21 → 11 frames (~0.5s instead of ~2s)
- confidence: 0.20 → 0.15 (catch more changes)
- min_duration: 1.0 → 0.5 seconds (allow half-bar changes)
Should detect 30-80 chords per song instead of 5 or 993.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- modules/chords.py +8 -8
modules/chords.py
CHANGED
|
@@ -270,13 +270,13 @@ def match_chord_template_with_confidence(chroma_frame, templates, focus='harmony
|
|
| 270 |
return best_chord, best_score
|
| 271 |
|
| 272 |
|
| 273 |
-
def extract_chords(audio_path, min_duration=
|
| 274 |
"""
|
| 275 |
Extract chords from audio file with musical timing.
|
| 276 |
|
| 277 |
Args:
|
| 278 |
audio_path: Path to audio file
|
| 279 |
-
min_duration: Minimum chord duration in seconds (default
|
| 280 |
|
| 281 |
Returns:
|
| 282 |
List of (timestamp, chord_name) tuples
|
|
@@ -288,15 +288,15 @@ def extract_chords(audio_path, min_duration=1.0):
|
|
| 288 |
# Load audio
|
| 289 |
y, sr = librosa.load(audio_path, sr=22050, duration=None)
|
| 290 |
|
| 291 |
-
# Use
|
| 292 |
-
# hop_length=
|
| 293 |
-
hop_length =
|
| 294 |
|
| 295 |
# Extract chroma features
|
| 296 |
chroma = librosa.feature.chroma_cqt(y=y, sr=sr, hop_length=hop_length)
|
| 297 |
|
| 298 |
-
#
|
| 299 |
-
chroma = scipy.ndimage.median_filter(chroma, size=(1,
|
| 300 |
|
| 301 |
templates = create_chord_templates()
|
| 302 |
|
|
@@ -312,7 +312,7 @@ def extract_chords(audio_path, min_duration=1.0):
|
|
| 312 |
consolidated = []
|
| 313 |
current_chord = None
|
| 314 |
current_start = 0.0
|
| 315 |
-
confidence_threshold = 0.
|
| 316 |
|
| 317 |
for time, chord, conf in raw_chords:
|
| 318 |
if conf >= confidence_threshold:
|
|
|
|
| 270 |
return best_chord, best_score
|
| 271 |
|
| 272 |
|
| 273 |
+
def extract_chords(audio_path, min_duration=0.5):
|
| 274 |
"""
|
| 275 |
Extract chords from audio file with musical timing.
|
| 276 |
|
| 277 |
Args:
|
| 278 |
audio_path: Path to audio file
|
| 279 |
+
min_duration: Minimum chord duration in seconds (default 0.5s for half-bar changes)
|
| 280 |
|
| 281 |
Returns:
|
| 282 |
List of (timestamp, chord_name) tuples
|
|
|
|
| 288 |
# Load audio
|
| 289 |
y, sr = librosa.load(audio_path, sr=22050, duration=None)
|
| 290 |
|
| 291 |
+
# Use moderate hop for reasonable time resolution
|
| 292 |
+
# hop_length=1024 at 22050Hz = ~46ms per frame
|
| 293 |
+
hop_length = 1024
|
| 294 |
|
| 295 |
# Extract chroma features
|
| 296 |
chroma = librosa.feature.chroma_cqt(y=y, sr=sr, hop_length=hop_length)
|
| 297 |
|
| 298 |
+
# Moderate smoothing - median filter across 11 frames (~0.5 seconds)
|
| 299 |
+
chroma = scipy.ndimage.median_filter(chroma, size=(1, 11))
|
| 300 |
|
| 301 |
templates = create_chord_templates()
|
| 302 |
|
|
|
|
| 312 |
consolidated = []
|
| 313 |
current_chord = None
|
| 314 |
current_start = 0.0
|
| 315 |
+
confidence_threshold = 0.15 # Lower threshold to catch more chord changes
|
| 316 |
|
| 317 |
for time, chord, conf in raw_chords:
|
| 318 |
if conf >= confidence_threshold:
|