Use average cents for target range tracking

- Replace cumulative_trans with average cents of actual chord
- More accurate register targeting using current chord position
- Test with max_path=150 shows reaching ~400 Hz target (2 octaves)
This commit is contained in:
Michael Winter 2026-03-14 03:09:46 +01:00
parent 2fe8737cfe
commit cc3c1ab971

View file

@ -203,7 +203,7 @@ class PathFinder:
edge, path, voice_stay_count, config, cumulative_trans edge, path, voice_stay_count, config, cumulative_trans
) * config.get("weight_dca", 1) ) * config.get("weight_dca", 1)
w += self._factor_target_range( w += self._factor_target_range(
edge_data, path, config, cumulative_trans edge, path, config, cumulative_trans
) * config.get("weight_target_range", 1) ) * config.get("weight_target_range", 1)
weights.append(w) weights.append(w)
@ -338,7 +338,7 @@ class PathFinder:
def _factor_target_range( def _factor_target_range(
self, self,
edge_data: dict, edge: tuple,
path: list, path: list,
config: dict, config: dict,
cumulative_trans: "Pitch | None", cumulative_trans: "Pitch | None",
@ -346,6 +346,7 @@ class PathFinder:
"""Returns factor based on movement toward target. """Returns factor based on movement toward target.
Target progresses based on position in path. Target progresses based on position in path.
Uses average cents of current chord for accurate targeting.
Factor > 1.0 if moving toward target, < 1.0 if moving away. Factor > 1.0 if moving toward target, < 1.0 if moving away.
""" """
if config.get("weight_target_range", 1) == 0: if config.get("weight_target_range", 1) == 0:
@ -364,17 +365,29 @@ class PathFinder:
progress = len(path) / max_path progress = len(path) / max_path
current_target = progress * target_cents current_target = progress * target_cents
current_cumulative_cents = cumulative_trans.to_cents() current_chord = path[-1]
current_avg_cents = sum(p.to_cents() for p in current_chord.pitches) / len(
current_chord.pitches
)
edge_data = edge[2]
next_graph_node = edge[1]
edge_trans = edge_data.get("transposition") edge_trans = edge_data.get("transposition")
new_cumulative = cumulative_trans.transpose(edge_trans) if edge_trans is not None:
new_cumulative_cents = new_cumulative.to_cents() candidate_transposed = next_graph_node.transpose(
cumulative_trans.transpose(edge_trans)
)
else:
candidate_transposed = next_graph_node.transpose(cumulative_trans)
candidate_avg_cents = sum(
p.to_cents() for p in candidate_transposed.pitches
) / len(candidate_transposed.pitches)
if current_target <= 0: if current_target <= 0:
return 1.0 return 1.0
dist_before = abs(current_cumulative_cents - current_target) dist_before = abs(current_avg_cents - current_target)
dist_after = abs(new_cumulative_cents - current_target) dist_after = abs(candidate_avg_cents - current_target)
if dist_before == 0: if dist_before == 0:
return 1.0 return 1.0