Add voice crossing check - reject edges where voices cross

- Movement map must be identity (0->0, 1->1, 2->2) to pass
- If any voice moves to a different position, weight = 0
This commit is contained in:
Michael Winter 2026-03-12 19:19:47 +01:00
parent d4cdd86e85
commit e13e9ba3bc

View file

@ -830,10 +830,14 @@ class PathFinder:
if edge_data.get("is_directly_tunable", False):
w *= 10
# Voice crossing weight (prefer no crossing)
# Voice crossing check - reject edges where voices cross
if config.get("voice_crossing", False):
# Simplified: prefer edges where more pitches stay in order
w *= 10
# Check if movement map is identity (0->0, 1->1, 2->2, etc.)
# If any voice moves to a different position, that's a crossing
num_voices = len(edge[0].pitches)
is_identity = all(movements.get(i) == i for i in range(num_voices))
if not is_identity:
w = 0.0 # Reject edges with voice crossing
weights.append(w)